|
12 | 12 | @mock.patch.object(connection.features, "supports_atlas_search", False)
|
13 | 13 | class UnsupportedSearchIndexesTests(TestCase):
|
14 | 14 | def test_search_index_not_created(self):
|
15 |
| - with connection.schema_editor() as editor: |
16 |
| - index = SearchIndex(name="recent_test_idx", fields=["number"]) |
17 |
| - with self.assertNumQueries(0): |
18 |
| - editor.add_index(index=index, model=SearchIndexTestModel) |
| 15 | + index = SearchIndex(name="recent_test_idx", fields=["number"]) |
| 16 | + with connection.schema_editor() as editor, self.assertNumQueries(0): |
| 17 | + editor.add_index(index=index, model=SearchIndexTestModel) |
19 | 18 | self.assertNotIn(
|
20 | 19 | index.name,
|
21 | 20 | connection.introspection.get_constraints(
|
22 | 21 | cursor=None,
|
23 | 22 | table_name=SearchIndexTestModel._meta.db_table,
|
24 | 23 | ),
|
25 | 24 | )
|
| 25 | + with connection.schema_editor() as editor, self.assertNumQueries(0): |
| 26 | + editor.remove_index(index=index, model=SearchIndexTestModel) |
26 | 27 |
|
27 | 28 | def test_vector_index_not_created(self):
|
28 |
| - with connection.schema_editor() as editor: |
29 |
| - index = VectorSearchIndex(name="recent_test_idx", fields=["number"]) |
30 |
| - with self.assertNumQueries(0): |
31 |
| - editor.add_index(index=index, model=SearchIndexTestModel) |
| 29 | + index = VectorSearchIndex(name="recent_test_idx", fields=["number"]) |
| 30 | + with connection.schema_editor() as editor, self.assertNumQueries(0): |
| 31 | + editor.add_index(index=index, model=SearchIndexTestModel) |
32 | 32 | self.assertNotIn(
|
33 | 33 | index.name,
|
34 | 34 | connection.introspection.get_constraints(
|
35 | 35 | cursor=None,
|
36 | 36 | table_name=SearchIndexTestModel._meta.db_table,
|
37 | 37 | ),
|
38 | 38 | )
|
| 39 | + with connection.schema_editor() as editor, self.assertNumQueries(0): |
| 40 | + editor.remove_index(index=index, model=SearchIndexTestModel) |
39 | 41 |
|
40 | 42 |
|
41 | 43 | class SearchIndexTests(SimpleTestCase):
|
@@ -68,6 +70,7 @@ def test_no_extra_kargs(self):
|
68 | 70 | def test_deconstruct(self):
|
69 | 71 | index = VectorSearchIndex(name="recent_test_idx", fields=["number"])
|
70 | 72 | name, args, kwargs = index.deconstruct()
|
| 73 | + self.assertEqual(kwargs, {"name": "recent_test_idx", "fields": ["number"]}) |
71 | 74 | new = VectorSearchIndex(*args, **kwargs)
|
72 | 75 | self.assertEqual(new.similarities, index.similarities)
|
73 | 76 |
|
@@ -255,3 +258,89 @@ def test_multiple_fields(self):
|
255 | 258 | finally:
|
256 | 259 | with connection.schema_editor() as editor:
|
257 | 260 | editor.remove_index(index=index, model=SearchIndexTestModel)
|
| 261 | + |
| 262 | + def test_similarities_value(self): |
| 263 | + index = VectorSearchIndex( |
| 264 | + name="recent_test_idx", |
| 265 | + fields=["vector_float", "vector_integer"], |
| 266 | + similarities="euclidean", |
| 267 | + ) |
| 268 | + with connection.schema_editor() as editor: |
| 269 | + editor.add_index(index=index, model=SearchIndexTestModel) |
| 270 | + try: |
| 271 | + index_info = connection.introspection.get_constraints( |
| 272 | + cursor=None, |
| 273 | + table_name=SearchIndexTestModel._meta.db_table, |
| 274 | + ) |
| 275 | + expected_options = { |
| 276 | + "latestDefinition": { |
| 277 | + "fields": [ |
| 278 | + { |
| 279 | + "numDimensions": 10, |
| 280 | + "path": "vector_float", |
| 281 | + "similarity": "euclidean", |
| 282 | + "type": "vector", |
| 283 | + }, |
| 284 | + { |
| 285 | + "numDimensions": 10, |
| 286 | + "path": "vector_integer", |
| 287 | + "similarity": "euclidean", |
| 288 | + "type": "vector", |
| 289 | + }, |
| 290 | + ] |
| 291 | + }, |
| 292 | + "latestVersion": 0, |
| 293 | + "name": "recent_test_idx", |
| 294 | + "queryable": False, |
| 295 | + "type": "vectorSearch", |
| 296 | + } |
| 297 | + self.assertCountEqual(index_info[index.name]["columns"], index.fields) |
| 298 | + index_info[index.name]["options"].pop("id") |
| 299 | + index_info[index.name]["options"].pop("status") |
| 300 | + self.assertEqual(index_info[index.name]["options"], expected_options) |
| 301 | + finally: |
| 302 | + with connection.schema_editor() as editor: |
| 303 | + editor.remove_index(index=index, model=SearchIndexTestModel) |
| 304 | + |
| 305 | + def test_similarities_list(self): |
| 306 | + index = VectorSearchIndex( |
| 307 | + name="recent_test_idx", |
| 308 | + fields=["vector_float", "vector_integer"], |
| 309 | + similarities=["cosine", "euclidean"], |
| 310 | + ) |
| 311 | + with connection.schema_editor() as editor: |
| 312 | + editor.add_index(index=index, model=SearchIndexTestModel) |
| 313 | + try: |
| 314 | + index_info = connection.introspection.get_constraints( |
| 315 | + cursor=None, |
| 316 | + table_name=SearchIndexTestModel._meta.db_table, |
| 317 | + ) |
| 318 | + expected_options = { |
| 319 | + "latestDefinition": { |
| 320 | + "fields": [ |
| 321 | + { |
| 322 | + "numDimensions": 10, |
| 323 | + "path": "vector_float", |
| 324 | + "similarity": "cosine", |
| 325 | + "type": "vector", |
| 326 | + }, |
| 327 | + { |
| 328 | + "numDimensions": 10, |
| 329 | + "path": "vector_integer", |
| 330 | + "similarity": "euclidean", |
| 331 | + "type": "vector", |
| 332 | + }, |
| 333 | + ] |
| 334 | + }, |
| 335 | + "latestVersion": 0, |
| 336 | + "name": "recent_test_idx", |
| 337 | + "queryable": False, |
| 338 | + "type": "vectorSearch", |
| 339 | + } |
| 340 | + self.assertCountEqual(index_info[index.name]["columns"], index.fields) |
| 341 | + index_info[index.name]["options"].pop("id") |
| 342 | + index_info[index.name]["options"].pop("status") |
| 343 | + self.assertEqual(index_info[index.name]["options"], expected_options) |
| 344 | + finally: |
| 345 | + with connection.schema_editor() as editor: |
| 346 | + editor.remove_index(index=index, model=SearchIndexTestModel) |
0 commit comments