mirror of
https://github.com/qdrant/qdrant.git
synced 2026-09-29 09:27:53 -05:00
* 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>
208 lines
6.5 KiB
Rust
208 lines
6.5 KiB
Rust
use std::collections::HashMap;
|
|
use std::path::Path;
|
|
|
|
use segment::data_types::named_vectors::NamedVectors;
|
|
use segment::data_types::vectors::{only_default_vector, VectorElementType};
|
|
use segment::entry::entry_point::SegmentEntry;
|
|
use segment::segment::Segment;
|
|
use segment::segment_constructor::build_segment;
|
|
use segment::segment_constructor::simple_segment_constructor::build_simple_segment;
|
|
use segment::types::{Distance, Indexes, SegmentConfig, VectorDataConfig};
|
|
use serde_json::json;
|
|
|
|
pub fn empty_segment(path: &Path) -> Segment {
|
|
build_simple_segment(path, 4, Distance::Dot).unwrap()
|
|
}
|
|
|
|
#[allow(dead_code)]
|
|
pub fn build_segment_1(path: &Path) -> Segment {
|
|
let mut segment1 = empty_segment(path);
|
|
|
|
let vec1 = vec![1.0, 0.0, 1.0, 1.0];
|
|
let vec2 = vec![1.0, 0.0, 1.0, 0.0];
|
|
let vec3 = vec![1.0, 1.0, 1.0, 1.0];
|
|
let vec4 = vec![1.0, 1.0, 0.0, 1.0];
|
|
let vec5 = vec![1.0, 0.0, 0.0, 0.0];
|
|
|
|
segment1
|
|
.upsert_vector(1, 1.into(), &only_default_vector(&vec1))
|
|
.unwrap();
|
|
segment1
|
|
.upsert_vector(2, 2.into(), &only_default_vector(&vec2))
|
|
.unwrap();
|
|
segment1
|
|
.upsert_vector(3, 3.into(), &only_default_vector(&vec3))
|
|
.unwrap();
|
|
segment1
|
|
.upsert_vector(4, 4.into(), &only_default_vector(&vec4))
|
|
.unwrap();
|
|
segment1
|
|
.upsert_vector(5, 5.into(), &only_default_vector(&vec5))
|
|
.unwrap();
|
|
|
|
let payload_key = "color";
|
|
|
|
let payload_option1 = json!({ payload_key: vec!["red".to_owned()] }).into();
|
|
let payload_option2 = json!({ payload_key: vec!["red".to_owned(), "blue".to_owned()] }).into();
|
|
let payload_option3 = json!({ payload_key: vec!["blue".to_owned()] }).into();
|
|
|
|
segment1.set_payload(6, 1.into(), &payload_option1).unwrap();
|
|
segment1.set_payload(6, 2.into(), &payload_option1).unwrap();
|
|
segment1.set_payload(6, 3.into(), &payload_option3).unwrap();
|
|
segment1.set_payload(6, 4.into(), &payload_option2).unwrap();
|
|
segment1.set_payload(6, 5.into(), &payload_option2).unwrap();
|
|
|
|
segment1
|
|
}
|
|
|
|
#[allow(dead_code)]
|
|
pub fn build_segment_2(path: &Path) -> Segment {
|
|
let mut segment2 = empty_segment(path);
|
|
|
|
let vec1 = vec![-1.0, 0.0, 1.0, 1.0];
|
|
let vec2 = vec![-1.0, 0.0, 1.0, 0.0];
|
|
let vec3 = vec![-1.0, 1.0, 1.0, 1.0];
|
|
let vec4 = vec![-1.0, 1.0, 0.0, 1.0];
|
|
let vec5 = vec![-1.0, 0.0, 0.0, 0.0];
|
|
|
|
segment2
|
|
.upsert_vector(11, 11.into(), &only_default_vector(&vec1))
|
|
.unwrap();
|
|
segment2
|
|
.upsert_vector(12, 12.into(), &only_default_vector(&vec2))
|
|
.unwrap();
|
|
segment2
|
|
.upsert_vector(13, 13.into(), &only_default_vector(&vec3))
|
|
.unwrap();
|
|
segment2
|
|
.upsert_vector(14, 14.into(), &only_default_vector(&vec4))
|
|
.unwrap();
|
|
segment2
|
|
.upsert_vector(15, 15.into(), &only_default_vector(&vec5))
|
|
.unwrap();
|
|
|
|
let payload_key = "color";
|
|
|
|
let payload_option1 = json!({ payload_key: vec!["red".to_owned()] }).into();
|
|
let payload_option2 = json!({ payload_key: vec!["red".to_owned(), "blue".to_owned()] }).into();
|
|
let payload_option3 = json!({ payload_key: vec!["blue".to_owned()] }).into();
|
|
|
|
segment2
|
|
.set_payload(16, 11.into(), &payload_option1)
|
|
.unwrap();
|
|
segment2
|
|
.set_payload(16, 12.into(), &payload_option1)
|
|
.unwrap();
|
|
segment2
|
|
.set_payload(16, 13.into(), &payload_option3)
|
|
.unwrap();
|
|
segment2
|
|
.set_payload(16, 14.into(), &payload_option2)
|
|
.unwrap();
|
|
segment2
|
|
.set_payload(16, 15.into(), &payload_option2)
|
|
.unwrap();
|
|
|
|
segment2
|
|
}
|
|
|
|
#[allow(dead_code)]
|
|
pub fn build_segment_3(path: &Path) -> Segment {
|
|
let mut segment3 = build_segment(
|
|
path,
|
|
&SegmentConfig {
|
|
vector_data: HashMap::from([
|
|
(
|
|
"vector1".to_owned(),
|
|
VectorDataConfig {
|
|
size: 4,
|
|
distance: Distance::Dot,
|
|
},
|
|
),
|
|
(
|
|
"vector2".to_owned(),
|
|
VectorDataConfig {
|
|
size: 1,
|
|
distance: Distance::Dot,
|
|
},
|
|
),
|
|
(
|
|
"vector3".to_owned(),
|
|
VectorDataConfig {
|
|
size: 4,
|
|
distance: Distance::Euclid,
|
|
},
|
|
),
|
|
]),
|
|
index: Indexes::Plain {},
|
|
storage_type: Default::default(),
|
|
payload_storage_type: Default::default(),
|
|
},
|
|
)
|
|
.unwrap();
|
|
|
|
let collect_points_data = |vectors: &[Vec<VectorElementType>]| {
|
|
NamedVectors::from([
|
|
("vector1".to_owned(), vectors[0].clone()),
|
|
("vector2".to_owned(), vectors[1].clone()),
|
|
("vector3".to_owned(), vectors[2].clone()),
|
|
])
|
|
};
|
|
|
|
let vec1 = [
|
|
vec![1.0, 0.0, 1.0, 1.0],
|
|
vec![0.0],
|
|
vec![-1.0, 0.0, 1.0, 1.0],
|
|
];
|
|
let vec2 = [
|
|
vec![1.0, 0.0, 1.0, 0.0],
|
|
vec![1.0],
|
|
vec![-1.0, 0.0, 1.0, 1.0],
|
|
];
|
|
let vec3 = [
|
|
vec![1.0, 1.0, 1.0, 1.0],
|
|
vec![2.0],
|
|
vec![-1.0, 0.0, 1.0, 1.0],
|
|
];
|
|
let vec4 = [
|
|
vec![1.0, 1.0, 0.0, 1.0],
|
|
vec![3.0],
|
|
vec![-1.0, 0.0, 1.0, 1.0],
|
|
];
|
|
let vec5 = [
|
|
vec![1.0, 0.0, 0.0, 0.0],
|
|
vec![4.0],
|
|
vec![-1.0, 0.0, 1.0, 1.0],
|
|
];
|
|
|
|
segment3
|
|
.upsert_vector(1, 1.into(), &collect_points_data(&vec1))
|
|
.unwrap();
|
|
segment3
|
|
.upsert_vector(2, 2.into(), &collect_points_data(&vec2))
|
|
.unwrap();
|
|
segment3
|
|
.upsert_vector(3, 3.into(), &collect_points_data(&vec3))
|
|
.unwrap();
|
|
segment3
|
|
.upsert_vector(4, 4.into(), &collect_points_data(&vec4))
|
|
.unwrap();
|
|
segment3
|
|
.upsert_vector(5, 5.into(), &collect_points_data(&vec5))
|
|
.unwrap();
|
|
|
|
let payload_key = "color";
|
|
|
|
let payload_option1 = json!({ payload_key: vec!["red".to_owned()] }).into();
|
|
let payload_option2 = json!({ payload_key: vec!["red".to_owned(), "blue".to_owned()] }).into();
|
|
let payload_option3 = json!({ payload_key: vec!["blue".to_owned()] }).into();
|
|
|
|
segment3.set_payload(6, 1.into(), &payload_option1).unwrap();
|
|
segment3.set_payload(6, 2.into(), &payload_option1).unwrap();
|
|
segment3.set_payload(6, 3.into(), &payload_option3).unwrap();
|
|
segment3.set_payload(6, 4.into(), &payload_option2).unwrap();
|
|
segment3.set_payload(6, 5.into(), &payload_option2).unwrap();
|
|
|
|
segment3
|
|
}
|