Skip to content

Commit 8ccb7ba

Browse files
committed
Docstring and search type mapping
1 parent 6f39188 commit 8ccb7ba

File tree

1 file changed

+34
-62
lines changed

1 file changed

+34
-62
lines changed

django_mongodb_backend/indexes.py

Lines changed: 34 additions & 62 deletions
Original file line numberDiff line numberDiff line change
@@ -4,24 +4,17 @@
44

55
from django.db import NotSupportedError
66
from django.db.models import (
7-
BooleanField,
8-
CharField,
9-
DateField,
10-
DateTimeField,
117
DecimalField,
128
FloatField,
139
Index,
14-
IntegerField,
15-
TextField,
16-
UUIDField,
1710
)
1811
from django.db.models.lookups import BuiltinLookup
1912
from django.db.models.sql.query import Query
2013
from django.db.models.sql.where import AND, XOR, WhereNode
2114
from pymongo import ASCENDING, DESCENDING
2215
from pymongo.operations import IndexModel, SearchIndexModel
2316

24-
from django_mongodb_backend.fields import ArrayField, ObjectIdAutoField, ObjectIdField
17+
from django_mongodb_backend.fields import ArrayField
2518

2619
from .query_utils import process_rhs
2720

@@ -116,7 +109,7 @@ def where_node_idx(self, compiler, connection):
116109
return mql
117110

118111

119-
def create_mongodb_index(
112+
def get_pymongo_index_model(
120113
self,
121114
model,
122115
schema_editor,
@@ -164,57 +157,41 @@ def create_mongodb_index(
164157

165158
class SearchIndex(Index):
166159
suffix = "search"
167-
# Maps Django internal type to atlas search index type.
168-
search_index_data_types = {
169-
"AutoField": "number",
170-
"BigAutoField": "number",
171-
"BinaryField": "string",
172-
"BooleanField": "boolean",
173-
"CharField": "string",
174-
"DateField": "date",
175-
"DateTimeField": "date",
176-
"DecimalField": "number",
177-
"DurationField": "number",
178-
"FileField": "string",
179-
"FilePathField": "string",
180-
"FloatField": "double",
181-
"IntegerField": "number",
182-
"BigIntegerField": "number",
183-
"GenericIPAddressField": "string",
184-
"JSONField": "document",
185-
"OneToOneField": "number",
186-
"PositiveBigIntegerField": "number",
187-
"PositiveIntegerField": "number",
188-
"PositiveSmallIntegerField": "number",
189-
"SlugField": "string",
190-
"SmallAutoField": "number",
191-
"SmallIntegerField": "number",
192-
"TextField": "string",
193-
"TimeField": "date",
194-
"UUIDField": "uuid",
195-
"ObjectIdAutoField": "objectId",
196-
"ObjectIdField": "objectId",
197-
"EmbeddedModelField": "embeddedDocuments",
198-
}
199160

200-
def __init__(self, *expressions, **kwargs):
201-
super().__init__(*expressions, **kwargs)
161+
# Maps Django internal type to atlas search index type.
162+
# Reference: https://www.mongodb.com/docs/atlas/atlas-search/define-field-mappings/#data-types
163+
def search_index_data_types(self, field, db_type):
164+
if field.get_internal_type() == "UUIDField":
165+
return "uuid"
166+
if field.get_internal_type() in ("ObjectIdAutoField", "ObjectIdField"):
167+
return "ObjectId"
168+
if field.get_internal_type() == "EmbeddedModelField":
169+
return "embeddedDocuments"
170+
if db_type in ("int", "long"):
171+
return "number"
172+
if db_type == "binData":
173+
return "string"
174+
if db_type == "bool":
175+
return "boolean"
176+
if db_type == "object":
177+
return "document"
178+
return db_type
202179

203-
def create_mongodb_index(
180+
def get_pymongo_index_model(
204181
self, model, schema_editor, field=None, unique=False, column_prefix=""
205182
):
206183
fields = {}
207184
for field_name, _ in self.fields_orders:
208185
field_ = model._meta.get_field(field_name)
209-
type_ = self.search_index_data_types[field_.get_internal_type()]
186+
type_ = self.search_index_data_types(field_, field_.db_type(schema_editor.connection))
210187
field_path = column_prefix + model._meta.get_field(field_name).column
211188
fields[field_path] = {"type": type_}
212189
return SearchIndexModel(
213190
definition={"mappings": {"dynamic": False, "fields": fields}}, name=self.name
214191
)
215192

216193

217-
class VectorSearchIndex(Index):
194+
class VectorSearchIndex(SearchIndex):
218195
suffix = "vector_search"
219196
ALLOWED_SIMILARITY_FUNCTIONS = frozenset(("euclidean", "cosine", "dotProduct"))
220197

@@ -235,7 +212,7 @@ def _check_similarity_functions(self, similarities):
235212
f"'are {','.join(self.ALLOWED_SIMILARITY_FUNCTIONS)}"
236213
)
237214

238-
def create_mongodb_index(
215+
def get_pymongo_index_model(
239216
self, model, schema_editor, field=None, unique=False, column_prefix=""
240217
):
241218
similarities = (
@@ -262,22 +239,17 @@ def create_mongodb_index(
262239
"similarity": next(similarities),
263240
}
264241
)
265-
elif isinstance(
266-
field_,
267-
BooleanField
268-
| IntegerField
269-
| DateField
270-
| DateTimeField
271-
| CharField
272-
| TextField
273-
| UUIDField
274-
| ObjectIdField
275-
| ObjectIdAutoField,
276-
):
277-
mappings["type"] = "filter"
278242
else:
279-
field_type = field_.get_internal_type()
280-
raise ValueError(f"Unsupported filter of type {field_type}.")
243+
field_type = field_.db_type(schema_editor.connection)
244+
search_type = self.search_index_data_types(field_, field_type)
245+
# filter - for fields that contain boolean, date, objectId, numeric,
246+
# string, or UUID values. Reference:
247+
# https://www.mongodb.com/docs/atlas/atlas-vector-search/vector-search-type/#atlas-vector-search-index-fields
248+
if search_type in ("number", "string", "boolean", "objectId", "uuid", "date"):
249+
mappings["type"] = "filter"
250+
else:
251+
field_type = field_.get_internal_type()
252+
raise ValueError(f"Unsupported filter of type {field_type}.")
281253
fields.append(mappings)
282254
return SearchIndexModel(definition={"fields": fields}, name=self.name, type="vectorSearch")
283255

0 commit comments

Comments
 (0)