11import itertools
22from collections import defaultdict
33
4- from django .core .checks import Error
4+ from django .core .checks import Error , Warning
55from django .db import NotSupportedError
66from django .db .models import DecimalField , FloatField , Index
77from django .db .models .lookups import BuiltinLookup
@@ -107,6 +107,23 @@ def where_node_idx(self, compiler, connection):
107107
108108class SearchIndex (Index ):
109109 suffix = "six"
110+ _error_id_prefix = "django_mongodb_backend.indexes.SearchIndex"
111+
112+ def check (self , model , connection ):
113+ errors = []
114+ if not connection .features .supports_search_indexes :
115+ errors .append (
116+ Warning (
117+ "This version of MongoDB does not support search indexes." ,
118+ hint = (
119+ "The index won't be created. Silence this warning if you "
120+ "don't care about it."
121+ ),
122+ obj = self ,
123+ id = f"{ self ._error_id_prefix } .W001" ,
124+ )
125+ )
126+ return errors
110127
111128 # Maps Django internal type to atlas search index type.
112129 # Reference: https://www.mongodb.com/docs/atlas/atlas-search/define-field-mappings/#data-types
@@ -144,14 +161,14 @@ def get_pymongo_index_model(
144161class VectorSearchIndex (SearchIndex ):
145162 suffix = "vsi"
146163 ALLOWED_SIMILARITY_FUNCTIONS = frozenset (("euclidean" , "cosine" , "dotProduct" ))
164+ _error_id_prefix = "django_mongodb_backend.indexes.VectorSearchIndex"
147165
148166 def __init__ (self , * expressions , similarities = "cosine" , ** kwargs ):
149167 super ().__init__ (* expressions , ** kwargs )
150168 self .similarities = similarities
151169
152170 def check (self , model , connection ):
153- errors = []
154- error_id_prefix = "django_mongodb_backend.indexes.VectorSearchIndex"
171+ errors = super ().check (model , connection )
155172 similarities = (
156173 self .similarities if isinstance (self .similarities , list ) else [self .similarities ]
157174 )
@@ -162,7 +179,7 @@ def check(self, model, connection):
162179 f"{ func } isn't a valid similarity function, options "
163180 f"are { ', ' .join (sorted (self .ALLOWED_SIMILARITY_FUNCTIONS ))} " ,
164181 obj = self ,
165- id = f"{ error_id_prefix } .E004" ,
182+ id = f"{ self . _error_id_prefix } .E004" ,
166183 )
167184 )
168185 for field_name , _ in self .fields_orders :
@@ -175,15 +192,15 @@ def check(self, model, connection):
175192 Error (
176193 "Atlas vector search requires size." ,
177194 obj = self ,
178- id = f"{ error_id_prefix } .E001" ,
195+ id = f"{ self . _error_id_prefix } .E001" ,
179196 )
180197 )
181198 if not isinstance (field_ .base_field , FloatField | DecimalField ):
182199 errors .append (
183200 Error (
184201 "Base type must be Float or Decimal." ,
185202 obj = self ,
186- id = f"{ error_id_prefix } .E002" ,
203+ id = f"{ self . _error_id_prefix } .E002" ,
187204 )
188205 )
189206 else :
@@ -197,7 +214,7 @@ def check(self, model, connection):
197214 Error (
198215 f"Unsupported filter of type { field_ .get_internal_type ()} ." ,
199216 obj = self ,
200- id = "django_mongodb_backend.indexes.VectorSearchIndex .E003" ,
217+ id = f" { self . _error_id_prefix } .E003" ,
201218 )
202219 )
203220 return errors
0 commit comments