use laurus::lexical::LexicalIndexWriter;
use laurus::lexical::NumericRangeQuery;
use laurus::lexical::NumericType;
use laurus::lexical::Query;
use laurus::lexical::{InvertedIndexWriter, InvertedIndexWriterConfig};
use laurus::storage::memory::{MemoryStorage, MemoryStorageConfig};
use laurus::{DataValue, Document};
use std::sync::Arc;
fn collect_matcher_results(mut m: Box<dyn laurus::lexical::query::matcher::Matcher>) -> Vec<u64> {
let mut docs = Vec::new();
while !m.is_exhausted() {
let doc_id = m.doc_id();
if doc_id == u64::MAX {
break;
}
docs.push(doc_id);
if !m.next().unwrap() {
break;
}
}
docs
}
#[test]
fn int64_array_any_value_in_range() {
let storage = Arc::new(MemoryStorage::new(MemoryStorageConfig::default()));
let mut writer = InvertedIndexWriter::new(
storage.clone(),
InvertedIndexWriterConfig {
max_buffered_docs: 10,
..Default::default()
},
)
.unwrap();
writer
.add_document(
Document::builder()
.add_int64_array("scores", vec![85, 72, 95])
.build(),
)
.unwrap();
writer
.add_document(
Document::builder()
.add_int64_array("scores", vec![60, 65])
.build(),
)
.unwrap();
writer
.add_document(
Document::builder()
.add_int64_array("scores", vec![88])
.build(),
)
.unwrap();
writer.commit().unwrap();
let reader = writer.build_reader().unwrap();
let q = NumericRangeQuery::new(
"scores",
NumericType::Integer,
Some(80.0),
Some(100.0),
true,
true,
);
let matched = collect_matcher_results(q.matcher(&*reader).unwrap());
assert_eq!(
matched,
vec![0, 2],
"doc 0 (95) and doc 2 (88) should match"
);
let q_low = NumericRangeQuery::new(
"scores",
NumericType::Integer,
Some(10.0),
Some(20.0),
true,
true,
);
let matched_low = collect_matcher_results(q_low.matcher(&*reader).unwrap());
assert!(
matched_low.is_empty(),
"no doc should match a disjoint range, got {matched_low:?}",
);
}
#[test]
fn int64_array_dedups_doc_when_multiple_values_match() {
let storage = Arc::new(MemoryStorage::new(MemoryStorageConfig::default()));
let mut writer = InvertedIndexWriter::new(
storage.clone(),
InvertedIndexWriterConfig {
max_buffered_docs: 10,
..Default::default()
},
)
.unwrap();
writer
.add_document(
Document::builder()
.add_int64_array("scores", vec![60, 80, 90])
.build(),
)
.unwrap();
writer.commit().unwrap();
let reader = writer.build_reader().unwrap();
let q = NumericRangeQuery::new(
"scores",
NumericType::Integer,
Some(50.0),
Some(100.0),
true,
true,
);
let matched = collect_matcher_results(q.matcher(&*reader).unwrap());
assert_eq!(matched, vec![0], "doc must be reported exactly once");
}
#[test]
fn float64_array_any_value_in_range() {
let storage = Arc::new(MemoryStorage::new(MemoryStorageConfig::default()));
let mut writer = InvertedIndexWriter::new(
storage.clone(),
InvertedIndexWriterConfig {
max_buffered_docs: 10,
..Default::default()
},
)
.unwrap();
writer
.add_document(
Document::builder()
.add_float64_array("prices", vec![12.5, 99.9, 7.0])
.build(),
)
.unwrap();
writer
.add_document(
Document::builder()
.add_float64_array("prices", vec![200.0, 250.0])
.build(),
)
.unwrap();
writer.commit().unwrap();
let reader = writer.build_reader().unwrap();
let q = NumericRangeQuery::new(
"prices",
NumericType::Float,
Some(50.0),
Some(100.0),
true,
true,
);
let matched = collect_matcher_results(q.matcher(&*reader).unwrap());
assert_eq!(matched, vec![0]);
}
#[test]
fn single_valued_field_unchanged_by_multi_valued_changes() {
let storage = Arc::new(MemoryStorage::new(MemoryStorageConfig::default()));
let mut writer = InvertedIndexWriter::new(
storage.clone(),
InvertedIndexWriterConfig {
max_buffered_docs: 10,
..Default::default()
},
)
.unwrap();
writer
.add_document(
Document::builder()
.add_field("age", DataValue::Int64(30))
.build(),
)
.unwrap();
writer
.add_document(
Document::builder()
.add_field("age", DataValue::Int64(20))
.build(),
)
.unwrap();
writer
.add_document(
Document::builder()
.add_field("age", DataValue::Int64(40))
.build(),
)
.unwrap();
writer.commit().unwrap();
let reader = writer.build_reader().unwrap();
let q = NumericRangeQuery::new(
"age",
NumericType::Integer,
Some(25.0),
Some(35.0),
true,
true,
);
let matched = collect_matcher_results(q.matcher(&*reader).unwrap());
assert_eq!(matched, vec![0]);
}