Files
qdrant/lib/segment/tests/segment_tests.rs
Ivan Pleshkov f6b2186193 [WIP] Many named vectors per point (#958)
* many named vectors per point (segment-level)

* operation result for dim function

* beautifulized vector name

* fix naming bug

* segment version migration

* fmt

* add segment tests

* are you happy clippy

* fix build

* [WIP] many named vectors per point (collection-level) (#975)

* config and search

* fix placeholders for proxy segment move

* remove VectorType from collection

* are you happy fmt

* vectors in grps messages

* create collections with vectors

* segment holder fixes

* are you happy fmt

* remove default vector name placeholders

* are you happy fmt

* are you happy clippy

* fix build

* fix web api

* are you happy clippy

* are you happy fmt

* record vector&vectors

* openapi update

* fix openapi integration tests

* segment builder fix todo

* vector names for update from segment

* remove unwrap

* backward compatibility

* upd openapi

* backward compatible PointStruct

* upd openapi

* fix record back-comp

* fmt

* vector configuration backward compatibility

* fix vetor storage size estimation

* fmt

* multi-vec segment test + index test

* fmt

* api integration tests

* [WIP] Named vectors struct (#1002)

* move to separate file

* named vectors as struct

* use cow

* fix build

* keys iterator

* avoid copy in PointStruct -> get_vectors

* avoid another copy

Co-authored-by: Andrey Vasnetsov <andrey@vasnetsov.com>

Co-authored-by: Andrey Vasnetsov <andrey@vasnetsov.com>
2022-09-11 20:59:23 +02:00

174 lines
4.9 KiB
Rust

mod fixtures;
#[cfg(test)]
mod tests {
use std::collections::HashSet;
use std::iter::FromIterator;
use segment::data_types::named_vectors::NamedVectors;
use segment::data_types::vectors::DEFAULT_VECTOR_NAME;
use segment::entry::entry_point::{OperationError, SegmentEntry};
use segment::types::{Condition, Filter, WithPayload};
use tempfile::Builder;
use crate::fixtures::segment::{build_segment_1, build_segment_3};
#[test]
fn test_point_exclusion() {
let dir = Builder::new().prefix("segment_dir").tempdir().unwrap();
let segment = build_segment_1(dir.path());
assert!(segment.has_point(3.into()));
let query_vector = vec![1.0, 1.0, 1.0, 1.0];
let res = segment
.search(
DEFAULT_VECTOR_NAME,
&query_vector,
&WithPayload::default(),
&false.into(),
None,
1,
None,
)
.unwrap();
let best_match = res.get(0).expect("Non-empty result");
assert_eq!(best_match.id, 3.into());
let ids: HashSet<_> = HashSet::from_iter([3.into()]);
let frt = Filter {
should: None,
must: None,
must_not: Some(vec![Condition::HasId(ids.into())]),
};
let res = segment
.search(
DEFAULT_VECTOR_NAME,
&query_vector,
&WithPayload::default(),
&false.into(),
Some(&frt),
1,
None,
)
.unwrap();
let best_match = res.get(0).expect("Non-empty result");
assert_ne!(best_match.id, 3.into());
let point_ids1: Vec<_> = segment.iter_points().collect();
let point_ids2: Vec<_> = segment.iter_points().collect();
assert!(!point_ids1.is_empty());
assert!(!point_ids2.is_empty());
assert_eq!(&point_ids1, &point_ids2)
}
#[test]
fn test_named_vector_search() {
let dir = Builder::new().prefix("segment_dir").tempdir().unwrap();
let segment = build_segment_3(dir.path());
assert!(segment.has_point(3.into()));
let query_vector = vec![1.0, 1.0, 1.0, 1.0];
let res = segment
.search(
"vector1",
&query_vector,
&WithPayload::default(),
&false.into(),
None,
1,
None,
)
.unwrap();
let best_match = res.get(0).expect("Non-empty result");
assert_eq!(best_match.id, 3.into());
let ids: HashSet<_> = HashSet::from_iter([3.into()]);
let frt = Filter {
should: None,
must: None,
must_not: Some(vec![Condition::HasId(ids.into())]),
};
let res = segment
.search(
"vector1",
&query_vector,
&WithPayload::default(),
&false.into(),
Some(&frt),
1,
None,
)
.unwrap();
let best_match = res.get(0).expect("Non-empty result");
assert_ne!(best_match.id, 3.into());
let point_ids1: Vec<_> = segment.iter_points().collect();
let point_ids2: Vec<_> = segment.iter_points().collect();
assert!(!point_ids1.is_empty());
assert!(!point_ids2.is_empty());
assert_eq!(&point_ids1, &point_ids2)
}
#[test]
fn test_missed_vector_name() {
let dir = Builder::new().prefix("segment_dir").tempdir().unwrap();
let mut segment = build_segment_3(dir.path());
let result = segment.upsert_vector(
6,
6.into(),
&NamedVectors::from([
("vector2".to_owned(), vec![10.]),
("vector3".to_owned(), vec![5., 6., 7., 8.]),
]),
);
if let Err(OperationError::MissedVectorName { received_name }) = result {
assert!(received_name == "vector1");
} else {
panic!("wrong upsert result")
}
}
#[test]
fn test_vector_name_not_exists() {
let dir = Builder::new().prefix("segment_dir").tempdir().unwrap();
let mut segment = build_segment_3(dir.path());
let result = segment.upsert_vector(
6,
6.into(),
&NamedVectors::from([
("vector1".to_owned(), vec![5., 6., 7., 8.]),
("vector2".to_owned(), vec![10.]),
("vector3".to_owned(), vec![5., 6., 7., 8.]),
("vector4".to_owned(), vec![5., 6., 7., 8.]),
]),
);
if let Err(OperationError::VectorNameNotExists { received_name }) = result {
assert!(received_name == "vector4");
} else {
panic!("wrong upsert result")
}
}
}