88from django .db .models .query import QuerySet
99from django .db .utils import DatabaseError
1010from django .test import TransactionTestCase , skipUnlessDBFeature
11- from pymongo .operations import SearchIndexModel
1211
1312from django_mongodb_backend .expressions import (
1413 CompoundExpression ,
2827 SearchVector ,
2928 SearchWildcard ,
3029)
31- from django_mongodb_backend .schema import DatabaseSchemaEditor
30+ from django_mongodb_backend .indexes import SearchIndex , VectorSearchIndex
3231
3332from .models import Article , Location , Writer
3433
@@ -75,22 +74,15 @@ class SearchUtilsMixin(TransactionTestCase):
7574 assertListEqual = _delayed_assertion (timeout = 2 )(TransactionTestCase .assertListEqual )
7675 assertQuerySetEqual = _delayed_assertion (timeout = 2 )(TransactionTestCase .assertQuerySetEqual )
7776
78- @staticmethod
79- def _get_collection (model ):
80- return connection .database .get_collection (model ._meta .db_table )
81-
8277 @classmethod
83- def create_search_index (cls , model , index_name , definition , type = "search" ):
84- # TODO: create/delete indexes using DatabaseSchemaEditor when
85- # SearchIndexes support mappings (INTPYTHON-729).
86- collection = cls ._get_collection (model )
87- idx = SearchIndexModel (definition = definition , name = index_name , type = type )
88- collection .create_search_index (idx )
89- DatabaseSchemaEditor .wait_until_index_created (collection , index_name )
78+ def create_search_index (cls , model , index_name , definition , index_cls = SearchIndex ):
79+ idx = index_cls (field_mappings = definition , name = index_name )
80+ with connection .schema_editor () as editor :
81+ editor .add_index (model , idx )
9082
9183 def drop_index ():
92- collection . drop_search_index ( index_name )
93- DatabaseSchemaEditor . wait_until_index_dropped ( collection , index_name )
84+ with connection . schema_editor () as editor :
85+ editor . remove_index ( model , idx )
9486
9587 cls .addClassCleanup (drop_index )
9688
@@ -101,12 +93,7 @@ def setUpClass(cls):
10193 cls .create_search_index (
10294 Article ,
10395 "equals_headline_index" ,
104- {
105- "mappings" : {
106- "dynamic" : False ,
107- "fields" : {"headline" : {"type" : "token" }, "number" : {"type" : "number" }},
108- }
109- },
96+ {"headline" : {"type" : "token" }, "number" : {"type" : "number" }},
11097 )
11198
11299 def setUp (self ):
@@ -167,32 +154,27 @@ def setUpClass(cls):
167154 Article ,
168155 "autocomplete_headline_index" ,
169156 {
170- "mappings" : {
171- "dynamic" : False ,
157+ "headline" : {
158+ "type" : "autocomplete" ,
159+ "analyzer" : "lucene.standard" ,
160+ "tokenization" : "edgeGram" ,
161+ "minGrams" : 3 ,
162+ "maxGrams" : 5 ,
163+ "foldDiacritics" : False ,
164+ },
165+ "writer" : {
166+ "type" : "document" ,
172167 "fields" : {
173- "headline " : {
168+ "name " : {
174169 "type" : "autocomplete" ,
175170 "analyzer" : "lucene.standard" ,
176171 "tokenization" : "edgeGram" ,
177172 "minGrams" : 3 ,
178173 "maxGrams" : 5 ,
179174 "foldDiacritics" : False ,
180- },
181- "writer" : {
182- "type" : "document" ,
183- "fields" : {
184- "name" : {
185- "type" : "autocomplete" ,
186- "analyzer" : "lucene.standard" ,
187- "tokenization" : "edgeGram" ,
188- "minGrams" : 3 ,
189- "maxGrams" : 5 ,
190- "foldDiacritics" : False ,
191- }
192- },
193- },
175+ }
194176 },
195- }
177+ },
196178 },
197179 )
198180
@@ -253,7 +235,7 @@ def setUpClass(cls):
253235 cls .create_search_index (
254236 Article ,
255237 "exists_body_index" ,
256- {"mappings" : { "dynamic" : False , "fields" : { " body" : {"type" : "token" }} }},
238+ {"body" : {"type" : "token" }},
257239 )
258240
259241 def setUp (self ):
@@ -282,7 +264,7 @@ def setUpClass(cls):
282264 cls .create_search_index (
283265 Article ,
284266 "in_headline_index" ,
285- {"mappings" : { "dynamic" : False , "fields" : { " headline" : {"type" : "token" }} }},
267+ {"headline" : {"type" : "token" }},
286268 )
287269
288270 def setUp (self ):
@@ -316,7 +298,7 @@ def setUpClass(cls):
316298 cls .create_search_index (
317299 Article ,
318300 "phrase_body_index" ,
319- {"mappings" : { "dynamic" : False , "fields" : { " body" : {"type" : "string" }} }},
301+ {"body" : {"type" : "string" }},
320302 )
321303
322304 def setUp (self ):
@@ -356,13 +338,8 @@ def setUpClass(cls):
356338 Article ,
357339 "query_string_index" ,
358340 {
359- "mappings" : {
360- "dynamic" : False ,
361- "fields" : {
362- "headline" : {"type" : "string" },
363- "body" : {"type" : "string" },
364- },
365- }
341+ "headline" : {"type" : "string" },
342+ "body" : {"type" : "string" },
366343 },
367344 )
368345
@@ -416,7 +393,7 @@ def setUpClass(cls):
416393 cls .create_search_index (
417394 Article ,
418395 "range_number_index" ,
419- {"mappings" : { "dynamic" : False , "fields" : { " number" : {"type" : "number" }} }},
396+ {"number" : {"type" : "number" }},
420397 )
421398 Article .objects .create (headline = "x" , number = 5 , body = "z" )
422399
@@ -453,12 +430,7 @@ def setUpClass(cls):
453430 cls .create_search_index (
454431 Article ,
455432 "regex_headline_index" ,
456- {
457- "mappings" : {
458- "dynamic" : False ,
459- "fields" : {"headline" : {"type" : "string" , "analyzer" : "lucene.keyword" }},
460- }
461- },
433+ {"headline" : {"type" : "string" , "analyzer" : "lucene.keyword" }},
462434 )
463435
464436 def setUp (self ):
@@ -498,7 +470,7 @@ def setUpClass(cls):
498470 cls .create_search_index (
499471 Article ,
500472 "text_body_index" ,
501- {"mappings" : { "dynamic" : False , "fields" : { " body" : {"type" : "string" }} }},
473+ {"body" : {"type" : "string" }},
502474 )
503475
504476 def setUp (self ):
@@ -560,12 +532,7 @@ def setUpClass(cls):
560532 cls .create_search_index (
561533 Article ,
562534 "wildcard_headline_index" ,
563- {
564- "mappings" : {
565- "dynamic" : False ,
566- "fields" : {"headline" : {"type" : "string" , "analyzer" : "lucene.keyword" }},
567- }
568- },
535+ {"headline" : {"type" : "string" , "analyzer" : "lucene.keyword" }},
569536 )
570537
571538 def setUp (self ):
@@ -603,12 +570,7 @@ def setUpClass(cls):
603570 cls .create_search_index (
604571 Article ,
605572 "geoshape_location_index" ,
606- {
607- "mappings" : {
608- "dynamic" : False ,
609- "fields" : {"location" : {"type" : "geo" , "indexShapes" : True }},
610- }
611- },
573+ {"location" : {"type" : "geo" , "indexShapes" : True }},
612574 )
613575
614576 def setUp (self ):
@@ -668,7 +630,7 @@ def setUpClass(cls):
668630 cls .create_search_index (
669631 Article ,
670632 "geowithin_location_index" ,
671- {"mappings" : { "dynamic" : False , "fields" : { " location" : {"type" : "geo" }} }},
633+ {"location" : {"type" : "geo" }},
672634 )
673635
674636 def setUp (self ):
@@ -743,12 +705,7 @@ def setUpClass(cls):
743705 cls .create_search_index (
744706 Article ,
745707 "mlt_index" ,
746- {
747- "mappings" : {
748- "dynamic" : False ,
749- "fields" : {"body" : {"type" : "string" }, "headline" : {"type" : "string" }},
750- }
751- },
708+ {"body" : {"type" : "string" }, "headline" : {"type" : "string" }},
752709 )
753710 cls .article1 = Article .objects .create (
754711 headline = "Space exploration" , number = 1 , body = "Webb telescope"
@@ -782,14 +739,9 @@ def setUpClass(cls):
782739 Article ,
783740 "compound_index" ,
784741 {
785- "mappings" : {
786- "dynamic" : False ,
787- "fields" : {
788- "headline" : [{"type" : "token" }, {"type" : "string" }],
789- "body" : {"type" : "string" },
790- "number" : {"type" : "number" },
791- },
792- }
742+ "headline" : [{"type" : "token" }, {"type" : "string" }],
743+ "body" : {"type" : "string" },
744+ "number" : {"type" : "number" },
793745 },
794746 )
795747
@@ -962,26 +914,20 @@ def test_str_returns_expected_format(self):
962914class SearchVectorTests (SearchUtilsMixin ):
963915 @classmethod
964916 def setUpClass (cls ):
965- cls .create_search_index (
966- Article ,
967- "vector_index" ,
968- {
969- "fields" : [
970- {
971- "type" : "vector" ,
972- "path" : "plot_embedding" ,
973- "numDimensions" : 3 ,
974- "similarity" : "cosine" ,
975- "quantization" : "scalar" ,
976- },
977- {
978- "type" : "filter" ,
979- "path" : "number" ,
980- },
981- ]
982- },
983- type = "vectorSearch" ,
917+ model = Article
918+ idx = VectorSearchIndex (
919+ fields = ["plot_embedding" , "number" ],
920+ name = "vector_index" ,
921+ similarities = "cosine" ,
984922 )
923+ with connection .schema_editor () as editor :
924+ editor .add_index (model , idx )
925+
926+ def drop_index ():
927+ with connection .schema_editor () as editor :
928+ editor .remove_index (model , idx )
929+
930+ cls .addClassCleanup (drop_index )
985931
986932 def setUp (self ):
987933 self .mars = Article .objects .create (
0 commit comments