44from django .db import connection
55from django .test import TestCase
66
7- from django_mongodb_backend .indexes import AtlasSearchIndex
7+ from django_mongodb_backend .indexes import AtlasSearchIndex , AtlasVectorSearchIndex
88
99from .models import Article , Data
1010
@@ -32,7 +32,7 @@ def assertAddRemoveIndex(self, editor, model, index):
3232 ),
3333 )
3434
35- def test_simple_atlas_index (self ):
35+ def test_simple (self ):
3636 with connection .schema_editor () as editor :
3737 index = AtlasSearchIndex (
3838 name = "recent_article_idx" ,
@@ -41,7 +41,7 @@ def test_simple_atlas_index(self):
4141 editor .add_index (index = index , model = Article )
4242 self .assertAddRemoveIndex (editor , Article , index )
4343
44- def test_multiple_fields_atlas_index (self ):
44+ def test_multiple_fields (self ):
4545 with connection .schema_editor () as editor :
4646 index = AtlasSearchIndex (
4747 name = "recent_article_idx" ,
@@ -106,6 +106,112 @@ def setUpTestData(cls):
106106 data = "{json: i}" ,
107107 embedded = Data (integer = i ),
108108 auto_now = datetime .datetime .now (),
109+ title_embedded = [0.1 ] * 10 ,
110+ description_embedded = [2.5 ] * 10 ,
111+ number_list = [2 ] * i ,
112+ name_list = [f"name_{ i } " ] * 10 ,
113+ )
114+ for i in range (5 )
115+ ]
116+ cls .objs = Article .objects .bulk_create (articles )
117+
118+
119+ class AtlasSearchIndexTests (TestCase ):
120+ # Schema editor is used to create the index to test that it works.
121+ # available_apps = ["indexes"]
122+ available_apps = None # could be removed?
123+
124+ def assertAddRemoveIndex (self , editor , model , index ):
125+ editor .add_index (index = index , model = model )
126+ self .assertIn (
127+ index .name ,
128+ connection .introspection .get_constraints (
129+ cursor = None ,
130+ table_name = model ._meta .db_table ,
131+ ),
132+ )
133+ editor .remove_index (index = index , model = model )
134+ self .assertNotIn (
135+ index .name ,
136+ connection .introspection .get_constraints (
137+ cursor = None ,
138+ table_name = model ._meta .db_table ,
139+ ),
140+ )
141+
142+ def test_simple_atlas_vector_search (self ):
143+ with connection .schema_editor () as editor :
144+ index = AtlasVectorSearchIndex (
145+ name = "recent_article_idx" ,
146+ fields = ["number" ],
147+ )
148+ editor .add_index (index = index , model = Article )
149+ self .assertAddRemoveIndex (editor , Article , index )
150+
151+ def test_multiple_fields (self ):
152+ with connection .schema_editor () as editor :
153+ index = AtlasVectorSearchIndex (
154+ name = "recent_article_idx" ,
155+ fields = ["headline" , "number" , "body" , "description_embedded" ],
156+ )
157+ editor .add_index (index = index , model = Article )
158+ index_info = connection .introspection .get_constraints (
159+ cursor = None ,
160+ table_name = Article ._meta .db_table ,
161+ )
162+ expected_options = {
163+ "latestDefinition" : {
164+ "fields" : [
165+ {"path" : "headline" , "type" : "filter" },
166+ {"path" : "number" , "type" : "filter" },
167+ {"path" : "body" , "type" : "filter" },
168+ {
169+ "numDimensions" : 10 ,
170+ "path" : "description_embedded" ,
171+ "similarity" : "cosine" ,
172+ "type" : "vector" ,
173+ },
174+ ]
175+ },
176+ "latestVersion" : 0 ,
177+ "name" : "recent_article_idx" ,
178+ "queryable" : False ,
179+ "type" : "vectorSearch" ,
180+ }
181+ self .assertCountEqual (index_info [index .name ]["columns" ], index .fields )
182+ index_info [index .name ]["options" ].pop ("id" )
183+ index_info [index .name ]["options" ].pop ("status" )
184+ self .assertEqual (index_info [index .name ]["options" ], expected_options )
185+ self .assertAddRemoveIndex (editor , Article , index )
186+
187+ def test_field_not_exists (self ):
188+ index = AtlasVectorSearchIndex (
189+ name = "recent_article_idx" ,
190+ fields = ["headline" , "number1" , "title_embedded" ],
191+ )
192+ with connection .schema_editor () as editor :
193+ msg = "Article has no field named 'number1'"
194+ with self .assertRaisesMessage (
195+ FieldDoesNotExist , msg
196+ ), connection .schema_editor () as editor :
197+ editor .add_index (index = index , model = Article )
198+
199+
200+ class AtlasSearchIndexTestsWithData (AtlasSearchIndexTests ):
201+ @classmethod
202+ def setUpTestData (cls ):
203+ articles = [
204+ Article (
205+ headline = f"Title { i } " ,
206+ number = i ,
207+ body = f"body { i } " ,
208+ data = "{json: i}" ,
209+ embedded = Data (integer = i ),
210+ auto_now = datetime .datetime .now (),
211+ title_embedded = [0.1 ] * 10 ,
212+ description_embedded = [2.5 ] * 10 ,
213+ number_list = [2 ] * i ,
214+ name_list = [f"name_{ i } " ] * 10 ,
109215 )
110216 for i in range (5 )
111217 ]
0 commit comments