mirror of
https://github.com/qdrant/qdrant.git
synced 2026-09-21 13:37:46 -05:00
test missed preprocess after segment update
This commit is contained in:
@@ -1,11 +1,14 @@
|
||||
use std::collections::HashSet;
|
||||
use std::iter::FromIterator;
|
||||
|
||||
use itertools::Itertools;
|
||||
use segment::data_types::named_vectors::NamedVectors;
|
||||
use segment::data_types::vectors::DEFAULT_VECTOR_NAME;
|
||||
use segment::data_types::vectors::{only_default_vector, VectorStruct, DEFAULT_VECTOR_NAME};
|
||||
use segment::entry::entry_point::{OperationError, SegmentEntry};
|
||||
use segment::fixtures::index_fixtures::random_vector;
|
||||
use segment::segment_constructor::load_segment;
|
||||
use segment::types::{Condition, Filter, WithPayload};
|
||||
use segment::segment_constructor::simple_segment_constructor::build_simple_segment;
|
||||
use segment::types::{Condition, Distance, Filter, SearchParams, WithPayload};
|
||||
use tempfile::Builder;
|
||||
|
||||
use crate::fixtures::segment::{build_segment_1, build_segment_3};
|
||||
@@ -205,3 +208,94 @@ fn ordered_deletion_test() {
|
||||
let best_match = res.get(0).expect("Non-empty result");
|
||||
assert_eq!(best_match.id, 3.into());
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_update_named_vector() {
|
||||
let num_points = 25;
|
||||
let dim = 4;
|
||||
let mut rng = rand::thread_rng();
|
||||
let distance = Distance::Cosine;
|
||||
let vectors = (0..num_points)
|
||||
.map(|_| random_vector(&mut rng, dim))
|
||||
.collect_vec();
|
||||
|
||||
let dir = Builder::new().prefix("segment_dir").tempdir().unwrap();
|
||||
let mut segment = build_simple_segment(dir.path(), dim, distance).unwrap();
|
||||
|
||||
for (i, vec) in vectors.iter().enumerate() {
|
||||
let i = i as u64;
|
||||
segment
|
||||
.upsert_point(i, i.into(), &only_default_vector(&vec))
|
||||
.unwrap();
|
||||
}
|
||||
|
||||
let query_vector = random_vector(&mut rng, dim);
|
||||
|
||||
// do exact search
|
||||
let search_params = SearchParams {
|
||||
hnsw_ef: None,
|
||||
exact: true,
|
||||
quantization: None,
|
||||
};
|
||||
let nearest_upsert = segment
|
||||
.search(
|
||||
DEFAULT_VECTOR_NAME,
|
||||
&query_vector,
|
||||
&false.into(),
|
||||
&true.into(),
|
||||
None,
|
||||
1,
|
||||
Some(&search_params),
|
||||
)
|
||||
.unwrap();
|
||||
let nearest_upsert = nearest_upsert.get(0).unwrap();
|
||||
|
||||
let sqrt_distance = |v: &[f32]| -> f32 { v.iter().map(|x| x * x).sum::<f32>().sqrt() };
|
||||
|
||||
// check if nearest_upsert is normalized
|
||||
match &nearest_upsert.vector {
|
||||
Some(VectorStruct::Single(v)) => {
|
||||
assert!((sqrt_distance(&v) - 1.).abs() < 1e-5);
|
||||
}
|
||||
Some(VectorStruct::Multi(v)) => {
|
||||
assert!((sqrt_distance(&v[DEFAULT_VECTOR_NAME]) - 1.).abs() < 1e-5);
|
||||
}
|
||||
_ => panic!("unexpected vector type"),
|
||||
}
|
||||
|
||||
// update vector using the same values
|
||||
for (i, vec) in vectors.iter().enumerate() {
|
||||
let i = i as u64;
|
||||
segment
|
||||
.update_vectors(i + num_points as u64, i.into(), only_default_vector(&vec))
|
||||
.unwrap();
|
||||
}
|
||||
|
||||
// do search after update
|
||||
let nearest_update = segment
|
||||
.search(
|
||||
DEFAULT_VECTOR_NAME,
|
||||
&query_vector,
|
||||
&false.into(),
|
||||
&true.into(),
|
||||
None,
|
||||
1,
|
||||
Some(&search_params),
|
||||
)
|
||||
.unwrap();
|
||||
let nearest_update = nearest_update.get(0).unwrap();
|
||||
|
||||
// check that nearest_upsert is normalized
|
||||
match &nearest_update.vector {
|
||||
Some(VectorStruct::Single(v)) => {
|
||||
assert!((sqrt_distance(&v) - 1.).abs() < 1e-5);
|
||||
}
|
||||
Some(VectorStruct::Multi(v)) => {
|
||||
assert!((sqrt_distance(&v[DEFAULT_VECTOR_NAME]) - 1.).abs() < 1e-5);
|
||||
}
|
||||
_ => panic!("unexpected vector type"),
|
||||
}
|
||||
|
||||
// check that nearests are the same
|
||||
assert_eq!(nearest_upsert.id, nearest_update.id);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user