@@ -7,8 +7,10 @@ use bson::{doc, oid::ObjectId, Document};
7
7
use futures_util:: TryStreamExt ;
8
8
9
9
use crate :: {
10
+ search_index:: SearchIndexType ,
10
11
test:: { log_uncaptured, spec:: unified_runner:: run_unified_tests} ,
11
12
Client ,
13
+ Collection ,
12
14
SearchIndexModel ,
13
15
} ;
14
16
@@ -272,3 +274,116 @@ async fn search_index_drop_not_found() {
272
274
273
275
coll0. drop_search_index ( "test-search-index" ) . await . unwrap ( ) ;
274
276
}
277
+
278
+ async fn wait_for_index ( coll : & Collection < Document > , name : & str ) -> Document {
279
+ let deadline = Instant :: now ( ) + Duration :: from_secs ( 60 * 5 ) ;
280
+ while Instant :: now ( ) < deadline {
281
+ let mut cursor = coll. list_search_indexes ( ) . name ( name) . await . unwrap ( ) ;
282
+ while let Some ( def) = cursor. try_next ( ) . await . unwrap ( ) {
283
+ if def. get_str ( "name" ) == Ok ( name) && def. get_bool ( "queryable" ) == Ok ( true ) {
284
+ return def;
285
+ }
286
+ }
287
+ tokio:: time:: sleep ( Duration :: from_secs ( 5 ) ) . await ;
288
+ }
289
+ panic ! ( "search index creation timed out" ) ;
290
+ }
291
+
292
+ // SearchIndex Case 7: Driver can successfully handle search index types when creating indexes
293
+ #[ tokio:: test]
294
+ async fn search_index_create_with_type ( ) {
295
+ if env:: var ( "INDEX_MANAGEMENT_TEST_PROSE" ) . is_err ( ) {
296
+ log_uncaptured ( "Skipping index management prose test: INDEX_MANAGEMENT_TEST_PROSE not set" ) ;
297
+ return ;
298
+ }
299
+ let client = Client :: test_builder ( ) . build ( ) . await ;
300
+ let coll_name = ObjectId :: new ( ) . to_hex ( ) ;
301
+ let db = client. database ( "search_index_test" ) ;
302
+ db. create_collection ( & coll_name) . await . unwrap ( ) ;
303
+ let coll0 = db. collection :: < Document > ( & coll_name) ;
304
+
305
+ let name = coll0
306
+ . create_search_index (
307
+ SearchIndexModel :: builder ( )
308
+ . name ( String :: from ( "test-search-index-case7-implicit" ) )
309
+ . definition ( doc ! { "mappings" : { "dynamic" : false } } )
310
+ . build ( ) ,
311
+ )
312
+ . await
313
+ . unwrap ( ) ;
314
+ assert_eq ! ( name, "test-search-index-case7-implicit" ) ;
315
+ let index1 = wait_for_index ( & coll0, & name) . await ;
316
+ assert_eq ! ( index1. get_str( "type" ) , Ok ( "search" ) ) ;
317
+
318
+ let name = coll0
319
+ . create_search_index (
320
+ SearchIndexModel :: builder ( )
321
+ . name ( String :: from ( "test-search-index-case7-explicit" ) )
322
+ . index_type ( SearchIndexType :: Search )
323
+ . definition ( doc ! { "mappings" : { "dynamic" : false } } )
324
+ . build ( ) ,
325
+ )
326
+ . await
327
+ . unwrap ( ) ;
328
+ assert_eq ! ( name, "test-search-index-case7-explicit" ) ;
329
+ let index2 = wait_for_index ( & coll0, & name) . await ;
330
+ assert_eq ! ( index2. get_str( "type" ) , Ok ( "search" ) ) ;
331
+
332
+ let name = coll0
333
+ . create_search_index (
334
+ SearchIndexModel :: builder ( )
335
+ . name ( String :: from ( "test-search-index-case7-vector" ) )
336
+ . index_type ( SearchIndexType :: VectorSearch )
337
+ . definition ( doc ! {
338
+ "fields" : [ {
339
+ "type" : "vector" ,
340
+ "path" : "plot_embedding" ,
341
+ "numDimensions" : 1536 ,
342
+ "similarity" : "euclidean" ,
343
+ } ]
344
+ } )
345
+ . build ( ) ,
346
+ )
347
+ . await
348
+ . unwrap ( ) ;
349
+ assert_eq ! ( name, "test-search-index-case7-vector" ) ;
350
+ let index3 = wait_for_index ( & coll0, & name) . await ;
351
+ assert_eq ! ( index3. get_str( "type" ) , Ok ( "vectorSearch" ) ) ;
352
+ }
353
+
354
+ // SearchIndex Case 8: Driver requires explicit type to create a vector search index
355
+ #[ tokio:: test]
356
+ async fn search_index_requires_explicit_vector ( ) {
357
+ if env:: var ( "INDEX_MANAGEMENT_TEST_PROSE" ) . is_err ( ) {
358
+ log_uncaptured ( "Skipping index management prose test: INDEX_MANAGEMENT_TEST_PROSE not set" ) ;
359
+ return ;
360
+ }
361
+ let client = Client :: test_builder ( ) . build ( ) . await ;
362
+ let coll_name = ObjectId :: new ( ) . to_hex ( ) ;
363
+ let db = client. database ( "search_index_test" ) ;
364
+ db. create_collection ( & coll_name) . await . unwrap ( ) ;
365
+ let coll0 = db. collection :: < Document > ( & coll_name) ;
366
+
367
+ let result = coll0
368
+ . create_search_index (
369
+ SearchIndexModel :: builder ( )
370
+ . name ( String :: from ( "test-search-index-case8-error" ) )
371
+ . definition ( doc ! {
372
+ "fields" : [ {
373
+ "type" : "vector" ,
374
+ "path" : "plot_embedding" ,
375
+ "numDimensions" : 1536 ,
376
+ "similarity" : "euclidean" ,
377
+ } ]
378
+ } )
379
+ . build ( ) ,
380
+ )
381
+ . await ;
382
+ assert ! (
383
+ result
384
+ . as_ref( )
385
+ . is_err_and( |e| e. to_string( ) . contains( "Attribute mappings missing" ) ) ,
386
+ "invalid result: {:?}" ,
387
+ result
388
+ ) ;
389
+ }
0 commit comments