@@ -8,8 +8,7 @@ use qdrant_client::Qdrant;
88use qdrant_client:: qdrant:: shard_key:: Key ;
99use qdrant_client:: qdrant:: {
1010 IdfParamsBuilder , PrefetchQueryBuilder , QuantizationSearchParamsBuilder , Query ,
11- QueryBatchPointsBuilder , QueryPointsBuilder , SearchParams , SearchParamsBuilder , SparseIndices ,
12- VectorInput ,
11+ QueryBatchPointsBuilder , QueryPointsBuilder , SearchParams , SearchParamsBuilder , VectorInput ,
1312} ;
1413use rand:: Rng ;
1514use rand:: RngExt ;
@@ -60,10 +59,7 @@ impl SearchProcessor {
6059 }
6160 }
6261
63- fn get_sparse_queries (
64- & self ,
65- rng : & mut impl Rng ,
66- ) -> Vec < ( Vec < f32 > , Option < SparseIndices > , Option < String > ) > {
62+ fn get_sparse_queries ( & self , rng : & mut impl Rng ) -> Vec < ( VectorInput , Option < String > ) > {
6763 if let Some ( sparsity) = self . args . sparse_vectors {
6864 let name = format ! (
6965 "{}_sparse" ,
@@ -77,19 +73,15 @@ impl SearchProcessor {
7773 let sparse_vector_tuples = random_sparse_vector ( rng, vocab_size, length) ;
7874 let ( indices, values) : ( Vec < _ > , Vec < _ > ) =
7975 sparse_vector_tuples. into_iter ( ) . unzip ( ) ;
80- let sparse_indices = SparseIndices { data : indices } ;
81- ( values, Some ( sparse_indices) , Some ( name. clone ( ) ) )
76+ ( VectorInput :: new_sparse ( indices, values) , Some ( name. clone ( ) ) )
8277 } )
8378 . collect ( )
8479 } else {
8580 panic ! ( "No sparse vectors configured" )
8681 }
8782 }
8883
89- fn get_dense_queries (
90- & self ,
91- rng : & mut impl Rng ,
92- ) -> Vec < ( Vec < f32 > , Option < SparseIndices > , Option < String > ) > {
84+ fn get_dense_queries ( & self , rng : & mut impl Rng ) -> Vec < ( VectorInput , Option < String > ) > {
9385 let name = if self . args . vectors_per_point > 1 {
9486 let name = random_vector_name ( rng, self . args . vectors_per_point ) ;
9587 Some ( name)
@@ -101,20 +93,26 @@ impl SearchProcessor {
10193
10294 ( 0 ..self . args . search_batch_size )
10395 . map ( |_| {
104- (
105- random_dense_vector ( rng, self . args . dim , is_uint) ,
106- None ,
107- name. clone ( ) ,
108- )
96+ // With --multivector-size, query with as many sub-vectors as each point holds.
97+ let vector = match self . args . multivector_size {
98+ Some ( count) => VectorInput :: new_multi (
99+ ( 0 ..count)
100+ . map ( |_| random_dense_vector ( rng, self . args . dim , is_uint) )
101+ . collect :: < Vec < _ > > ( ) ,
102+ ) ,
103+ None => {
104+ VectorInput :: new_dense ( random_dense_vector ( rng, self . args . dim , is_uint) )
105+ }
106+ } ;
107+ ( vector, name. clone ( ) )
109108 } )
110109 . collect ( )
111110 }
112111
113112 fn create_request_builder (
114113 & self ,
115114 query_filter : Option < qdrant_client:: qdrant:: Filter > ,
116- query_vectors : Vec < f32 > ,
117- sparse_indices : Option < SparseIndices > ,
115+ vector : VectorInput ,
118116 vector_name : Option < String > ,
119117 search_params : SearchParamsBuilder ,
120118 ) -> QueryPointsBuilder {
@@ -134,12 +132,6 @@ impl SearchProcessor {
134132 request_builder = request_builder. filter ( filter) ;
135133 }
136134
137- let vector = if let Some ( sparse_indices) = sparse_indices {
138- VectorInput :: new_sparse ( sparse_indices. data , query_vectors)
139- } else {
140- VectorInput :: new_dense ( query_vectors)
141- } ;
142-
143135 let query = Query :: new_nearest ( vector) ;
144136
145137 if let Some ( prefetch_limit) = self . args . prefetch {
@@ -246,11 +238,10 @@ impl SearchProcessor {
246238
247239 let query_points: Vec < _ > = query_batch
248240 . into_iter ( )
249- . map ( |( query_vectors , sparse_indices , vector_name) | {
241+ . map ( |( vector , vector_name) | {
250242 self . create_request_builder (
251243 query_filter. clone ( ) ,
252- query_vectors,
253- sparse_indices,
244+ vector,
254245 vector_name,
255246 search_params. clone ( ) ,
256247 )
@@ -395,3 +386,39 @@ impl Processor for SearchProcessor {
395386 self . args . search_batch_size
396387 }
397388}
389+
390+ #[ cfg( test) ]
391+ mod tests {
392+ use clap:: Parser ;
393+ use qdrant_client:: qdrant:: vector_input:: Variant ;
394+
395+ use super :: * ;
396+
397+ fn processor ( extra : & [ & str ] ) -> SearchProcessor {
398+ let mut argv = vec ! [ "bfb" , "--dim" , "8" ] ;
399+ argv. extend_from_slice ( extra) ;
400+ let args = Args :: parse_from ( argv) ;
401+ SearchProcessor :: new ( args, Arc :: new ( AtomicBool :: new ( false ) ) , vec ! [ ] , vec ! [ ] )
402+ }
403+
404+ #[ test]
405+ fn dense_query_without_multivector ( ) {
406+ let queries = processor ( & [ ] ) . get_dense_queries ( & mut rand:: rng ( ) ) ;
407+ match & queries[ 0 ] . 0 . variant {
408+ Some ( Variant :: Dense ( v) ) => assert_eq ! ( v. data. len( ) , 8 ) ,
409+ other => panic ! ( "expected a dense query, got {other:?}" ) ,
410+ }
411+ }
412+
413+ #[ test]
414+ fn multivector_query_matches_multivector_size ( ) {
415+ let queries = processor ( & [ "--multivector-size" , "4" ] ) . get_dense_queries ( & mut rand:: rng ( ) ) ;
416+ match & queries[ 0 ] . 0 . variant {
417+ Some ( Variant :: MultiDense ( m) ) => {
418+ assert_eq ! ( m. vectors. len( ) , 4 ) ;
419+ assert ! ( m. vectors. iter( ) . all( |v| v. data. len( ) == 8 ) ) ;
420+ }
421+ other => panic ! ( "expected a multivector query, got {other:?}" ) ,
422+ }
423+ }
424+ }
0 commit comments