pub trait Filter {
// Required method
fn allows(&self, tag: u64) -> bool;
// Provided methods
fn exact(&self, _id: u64) -> bool { ... }
fn narrowing(&self) -> bool { ... }
}Expand description
What decides whether the scan bothers with a member.
A filtered vector search is a recall lottery when the filter runs after the search: ask for ten English passages, get the best forty by vector, find three of them are English, and the other seven English passages that were nearer never had a chance. The fix is to filter inside the scan, so that only members that can be answers are ranked at all, and that means the thing the filter reads has to sit next to the codes rather than behind a lookup into somebody else’s table.
So every member carries a u64 tag, given at insert, and a filter is a
predicate on that tag. What the tag means is the caller’s business. A
handful of low cardinality attributes pack into it exactly, one field each,
and the filter is then exact. Anything wider goes through Signature,
which is exact in the direction that matters: it never rejects a member that
should have matched, so the caller’s real predicate over the answers still
decides.
A tag that is only a summary needs a second test somewhere, and the place
for it is Filter::exact, which sees the member’s id and can go and read
whatever the caller keyed by it. That runs only for members the tag let
through that are also near enough to be ranked, which is why it is allowed to
be the expensive one: an expression over a JSON string is fine there and
would not be fine in the scan.
Required Methods§
Provided Methods§
Sourcefn exact(&self, _id: u64) -> bool
fn exact(&self, _id: u64) -> bool
The second test, on the member’s id rather than on its tag.
Everything lets everything through by default, because for a filter whose tag says the whole truth there is nothing left to ask. Override it when the tag is a summary and the real predicate lives in a table of the caller’s, and keep the tag test as the cheap superset of it: a member the tag rejects never reaches here.
Sourcefn narrowing(&self) -> bool
fn narrowing(&self) -> bool
Whether this filter can turn members away.
A search that can be turned away has to be ready to look further than
probe partitions, because the nearest ones may not hold k members
that pass, and getting ready to costs something before the first
partition is read: the probe order has to be built widen times longer
than the search will use if it never widens. Saying no here is how a
search that cannot be turned away avoids paying for the case that cannot
happen to it. The default is yes, because a filter that answers wrongly
here returns short answers rather than slow ones.
Dyn Compatibility§
This trait is dyn compatible.
In older versions of Rust, dyn compatibility was called "object safety".