mirror of
https://github.com/qdrant/qdrant.git
synced 2026-08-03 08:30:55 -05:00
Plain search for inverted index (#3113)
This commit is contained in:
@@ -55,6 +55,23 @@ impl<'a> SearchContext<'a> {
|
||||
}
|
||||
}
|
||||
|
||||
/// Return all results that overlap with the query vector
|
||||
///
|
||||
/// The resulting sparse vectors are sorted by id and contains only values that overlap with the query vector
|
||||
///
|
||||
/// This is a plain search without any pruning
|
||||
fn plain_search(&mut self) -> Vec<(u32, SparseVector)> {
|
||||
let mut result = Vec::new();
|
||||
while let Some(next) = self.get_next() {
|
||||
// check for cancellation
|
||||
if self.is_stopped.load(Relaxed) {
|
||||
break;
|
||||
}
|
||||
result.push(next);
|
||||
}
|
||||
result
|
||||
}
|
||||
|
||||
/// Advance posting lists iterators and return the next candidate by increasing ids.
|
||||
///
|
||||
/// Example
|
||||
@@ -108,6 +125,26 @@ impl<'a> SearchContext<'a> {
|
||||
})
|
||||
}
|
||||
|
||||
fn get_next(&mut self) -> Option<(u32, SparseVector)> {
|
||||
let min_record_id = Self::next_min_id(&self.postings_iterators)?;
|
||||
let mut indices = vec![];
|
||||
let mut values = vec![];
|
||||
|
||||
// Iterate second time to advance posting iterators
|
||||
for posting_iterator in self.postings_iterators.iter_mut() {
|
||||
if let Some(element) = posting_iterator.posting_list_iterator.peek() {
|
||||
// accumulate indices & values for the current record id
|
||||
if element.record_id == min_record_id {
|
||||
let element = posting_iterator.posting_list_iterator.next().unwrap();
|
||||
indices.push(self.query.indices[posting_iterator.query_weight_offset]);
|
||||
values.push(element.weight)
|
||||
}
|
||||
}
|
||||
}
|
||||
let sparse_vector = SparseVector { indices, values };
|
||||
Some((min_record_id, sparse_vector))
|
||||
}
|
||||
|
||||
/// Returns the next min record id from all posting list iterators
|
||||
///
|
||||
/// returns None if all posting list iterators are exhausted
|
||||
@@ -966,4 +1003,102 @@ mod tests {
|
||||
3
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn plain_search_all_test() {
|
||||
let is_stopped = AtomicBool::new(false);
|
||||
let inverted_index_ram = InvertedIndexBuilder::new()
|
||||
.add(1, PostingList::from(vec![(1, 10.0), (2, 20.0)]))
|
||||
.add(2, PostingList::from(vec![(1, 10.0), (3, 30.0)]))
|
||||
.add(3, PostingList::from(vec![(1, 10.0), (2, 20.0), (3, 30.0)]))
|
||||
.build();
|
||||
|
||||
let mut search_context = SearchContext::new(
|
||||
SparseVector {
|
||||
indices: vec![1, 2, 3],
|
||||
values: vec![1.0, 1.0, 1.0],
|
||||
},
|
||||
3,
|
||||
&inverted_index_ram,
|
||||
&is_stopped,
|
||||
);
|
||||
|
||||
let sparse_vectors = search_context.plain_search();
|
||||
assert_eq!(
|
||||
sparse_vectors,
|
||||
vec![
|
||||
(
|
||||
1,
|
||||
SparseVector {
|
||||
indices: vec![1, 2, 3],
|
||||
values: vec![10.0, 10.0, 10.0]
|
||||
}
|
||||
),
|
||||
(
|
||||
2,
|
||||
SparseVector {
|
||||
indices: vec![1, 3],
|
||||
values: vec![20.0, 20.0]
|
||||
}
|
||||
),
|
||||
(
|
||||
3,
|
||||
SparseVector {
|
||||
indices: vec![2, 3],
|
||||
values: vec![30.0, 30.0]
|
||||
}
|
||||
),
|
||||
]
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn plain_search_gap_test() {
|
||||
let is_stopped = AtomicBool::new(false);
|
||||
let inverted_index_ram = InvertedIndexBuilder::new()
|
||||
.add(1, PostingList::from(vec![(1, 10.0), (2, 20.0)]))
|
||||
.add(2, PostingList::from(vec![(1, 10.0), (3, 30.0)]))
|
||||
.add(3, PostingList::from(vec![(1, 10.0), (2, 20.0), (3, 30.0)]))
|
||||
.build();
|
||||
|
||||
// query vector has a gap for dimension 2
|
||||
let mut search_context = SearchContext::new(
|
||||
SparseVector {
|
||||
indices: vec![1, 3],
|
||||
values: vec![1.0, 1.0],
|
||||
},
|
||||
3,
|
||||
&inverted_index_ram,
|
||||
&is_stopped,
|
||||
);
|
||||
|
||||
// the dimension 2 is absent in the result vectors
|
||||
let sparse_vectors = search_context.plain_search();
|
||||
assert_eq!(
|
||||
sparse_vectors,
|
||||
vec![
|
||||
(
|
||||
1,
|
||||
SparseVector {
|
||||
indices: vec![1, 3],
|
||||
values: vec![10.0, 10.0]
|
||||
}
|
||||
),
|
||||
(
|
||||
2,
|
||||
SparseVector {
|
||||
indices: vec![1, 3],
|
||||
values: vec![20.0, 20.0]
|
||||
}
|
||||
),
|
||||
(
|
||||
3,
|
||||
SparseVector {
|
||||
indices: vec![3],
|
||||
values: vec![30.0]
|
||||
}
|
||||
),
|
||||
]
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user