pub enum Filter {
Eq {
field: String,
value: Value,
},
In {
field: String,
values: Vec<Value>,
},
Range {
field: String,
gt: Option<f64>,
gte: Option<f64>,
lt: Option<f64>,
lte: Option<f64>,
},
And(Vec<Filter>),
Or(Vec<Filter>),
Not(Box<Filter>),
}Expand description
Metadata predicate applied during search.
Fields are addressed by dotted paths ("source.lang"). A record without
the field does not match positive predicates; NOT negates that result.
Variants§
Implementations§
Source§impl Filter
impl Filter
Sourcepub fn eq(field: impl Into<String>, value: impl Into<Value>) -> Self
pub fn eq(field: impl Into<String>, value: impl Into<Value>) -> Self
Examples found in repository?
examples/quickstart.rs (line 37)
9fn main() -> recern_vector::Result<()> {
10 let path = std::env::temp_dir().join("recern-vector-quickstart.rvec");
11 let _ = std::fs::remove_file(&path);
12 let _ = std::fs::remove_file(format!("{}.wal", path.display()));
13
14 let mut db = Database::create(&path)?;
15 let docs = db.create_collection("docs", CollectionConfig::new(32, Metric::Cosine))?;
16
17 // Batch insert: (id, vector, metadata). Built on all cores, atomic.
18 let records: Vec<_> = (0..10_000)
19 .map(|i| {
20 let vector: Vec<f32> = (0..32).map(|d| pseudo_random(i * 32 + d)).collect();
21 let lang = ["en", "de", "fr"][i % 3];
22 (
23 format!("doc-{i}"),
24 vector,
25 Some(json!({"lang": lang, "year": 2015 + i % 10})),
26 )
27 })
28 .collect();
29 let query = records[42].1.clone();
30 docs.upsert_many(records)?;
31 println!("{} records", docs.len());
32
33 // Search with a filter; explain() returns the hits and how they were found.
34 let filter = Filter::from_json(&json!({"lang": "en", "year": {"$gte": 2020}}))?;
35 // The same filter, built in code:
36 let _same = Filter::And(vec![
37 Filter::eq("lang", "en"),
38 Filter::between("year", Some(2020.0), None),
39 ]);
40 let report = docs.explain(&query, 3, &SearchOptions::default().filter(filter))?;
41 for hit in &report.hits {
42 println!(
43 " {:<10} distance={:.4} {}",
44 hit.id,
45 hit.distance,
46 hit.metadata.as_ref().unwrap()
47 );
48 }
49 println!(
50 "strategy={} visited={} selectivity={:.1}% time={:?}",
51 report.strategy,
52 report.visited,
53 report.filter_selectivity.unwrap_or(1.0) * 100.0,
54 report.elapsed
55 );
56
57 // Index health and recall against exact search.
58 let stats = docs.stats();
59 println!(
60 "layers={:?} unreachable={}",
61 stats.nodes_per_layer, stats.unreachable
62 );
63 let recall = docs.estimate_recall(&RecallOptions {
64 ef_values: vec![16, 64],
65 ..Default::default()
66 })?;
67 for point in &recall.points {
68 println!(
69 " ef={:<3} recall@{}={:.3}",
70 point.ef, recall.k, point.recall
71 );
72 }
73
74 db.save()?;
75 let reopened = Database::open(&path)?;
76 println!("reopened: {} records", reopened.collection("docs")?.len());
77 Ok(())
78}pub fn is_in( field: impl Into<String>, values: impl IntoIterator<Item = Value>, ) -> Self
Sourcepub fn between(
field: impl Into<String>,
gte: Option<f64>,
lte: Option<f64>,
) -> Self
pub fn between( field: impl Into<String>, gte: Option<f64>, lte: Option<f64>, ) -> Self
Inclusive range. Either bound may be omitted.
Examples found in repository?
examples/quickstart.rs (line 38)
9fn main() -> recern_vector::Result<()> {
10 let path = std::env::temp_dir().join("recern-vector-quickstart.rvec");
11 let _ = std::fs::remove_file(&path);
12 let _ = std::fs::remove_file(format!("{}.wal", path.display()));
13
14 let mut db = Database::create(&path)?;
15 let docs = db.create_collection("docs", CollectionConfig::new(32, Metric::Cosine))?;
16
17 // Batch insert: (id, vector, metadata). Built on all cores, atomic.
18 let records: Vec<_> = (0..10_000)
19 .map(|i| {
20 let vector: Vec<f32> = (0..32).map(|d| pseudo_random(i * 32 + d)).collect();
21 let lang = ["en", "de", "fr"][i % 3];
22 (
23 format!("doc-{i}"),
24 vector,
25 Some(json!({"lang": lang, "year": 2015 + i % 10})),
26 )
27 })
28 .collect();
29 let query = records[42].1.clone();
30 docs.upsert_many(records)?;
31 println!("{} records", docs.len());
32
33 // Search with a filter; explain() returns the hits and how they were found.
34 let filter = Filter::from_json(&json!({"lang": "en", "year": {"$gte": 2020}}))?;
35 // The same filter, built in code:
36 let _same = Filter::And(vec![
37 Filter::eq("lang", "en"),
38 Filter::between("year", Some(2020.0), None),
39 ]);
40 let report = docs.explain(&query, 3, &SearchOptions::default().filter(filter))?;
41 for hit in &report.hits {
42 println!(
43 " {:<10} distance={:.4} {}",
44 hit.id,
45 hit.distance,
46 hit.metadata.as_ref().unwrap()
47 );
48 }
49 println!(
50 "strategy={} visited={} selectivity={:.1}% time={:?}",
51 report.strategy,
52 report.visited,
53 report.filter_selectivity.unwrap_or(1.0) * 100.0,
54 report.elapsed
55 );
56
57 // Index health and recall against exact search.
58 let stats = docs.stats();
59 println!(
60 "layers={:?} unreachable={}",
61 stats.nodes_per_layer, stats.unreachable
62 );
63 let recall = docs.estimate_recall(&RecallOptions {
64 ef_values: vec![16, 64],
65 ..Default::default()
66 })?;
67 for point in &recall.points {
68 println!(
69 " ef={:<3} recall@{}={:.3}",
70 point.ef, recall.k, point.recall
71 );
72 }
73
74 db.save()?;
75 let reopened = Database::open(&path)?;
76 println!("reopened: {} records", reopened.collection("docs")?.len());
77 Ok(())
78}pub fn matches(&self, metadata: Option<&Value>) -> bool
Sourcepub fn from_json(value: &Value) -> Result<Self>
pub fn from_json(value: &Value) -> Result<Self>
Parses a MongoDB-style filter:
{"lang": "en", "year": {"$gte": 2020, "$lt": 2025}, "tag": {"$in": ["a", "b"]}}Top-level keys are combined with AND. Supported operators: $eq,
$in, $gt, $gte, $lt, $lte, and logical $and, $or, $not.
Examples found in repository?
examples/quickstart.rs (line 34)
9fn main() -> recern_vector::Result<()> {
10 let path = std::env::temp_dir().join("recern-vector-quickstart.rvec");
11 let _ = std::fs::remove_file(&path);
12 let _ = std::fs::remove_file(format!("{}.wal", path.display()));
13
14 let mut db = Database::create(&path)?;
15 let docs = db.create_collection("docs", CollectionConfig::new(32, Metric::Cosine))?;
16
17 // Batch insert: (id, vector, metadata). Built on all cores, atomic.
18 let records: Vec<_> = (0..10_000)
19 .map(|i| {
20 let vector: Vec<f32> = (0..32).map(|d| pseudo_random(i * 32 + d)).collect();
21 let lang = ["en", "de", "fr"][i % 3];
22 (
23 format!("doc-{i}"),
24 vector,
25 Some(json!({"lang": lang, "year": 2015 + i % 10})),
26 )
27 })
28 .collect();
29 let query = records[42].1.clone();
30 docs.upsert_many(records)?;
31 println!("{} records", docs.len());
32
33 // Search with a filter; explain() returns the hits and how they were found.
34 let filter = Filter::from_json(&json!({"lang": "en", "year": {"$gte": 2020}}))?;
35 // The same filter, built in code:
36 let _same = Filter::And(vec![
37 Filter::eq("lang", "en"),
38 Filter::between("year", Some(2020.0), None),
39 ]);
40 let report = docs.explain(&query, 3, &SearchOptions::default().filter(filter))?;
41 for hit in &report.hits {
42 println!(
43 " {:<10} distance={:.4} {}",
44 hit.id,
45 hit.distance,
46 hit.metadata.as_ref().unwrap()
47 );
48 }
49 println!(
50 "strategy={} visited={} selectivity={:.1}% time={:?}",
51 report.strategy,
52 report.visited,
53 report.filter_selectivity.unwrap_or(1.0) * 100.0,
54 report.elapsed
55 );
56
57 // Index health and recall against exact search.
58 let stats = docs.stats();
59 println!(
60 "layers={:?} unreachable={}",
61 stats.nodes_per_layer, stats.unreachable
62 );
63 let recall = docs.estimate_recall(&RecallOptions {
64 ef_values: vec![16, 64],
65 ..Default::default()
66 })?;
67 for point in &recall.points {
68 println!(
69 " ef={:<3} recall@{}={:.3}",
70 point.ef, recall.k, point.recall
71 );
72 }
73
74 db.save()?;
75 let reopened = Database::open(&path)?;
76 println!("reopened: {} records", reopened.collection("docs")?.len());
77 Ok(())
78}Trait Implementations§
impl StructuralPartialEq for Filter
Auto Trait Implementations§
impl Freeze for Filter
impl RefUnwindSafe for Filter
impl Send for Filter
impl Sync for Filter
impl Unpin for Filter
impl UnsafeUnpin for Filter
impl UnwindSafe for Filter
Blanket Implementations§
Source§impl<T> BorrowMut<T> for Twhere
T: ?Sized,
impl<T> BorrowMut<T> for Twhere
T: ?Sized,
Source§fn borrow_mut(&mut self) -> &mut T
fn borrow_mut(&mut self) -> &mut T
Mutably borrows from an owned value. Read more