@@ -109,9 +109,38 @@ class SearchIndex(Index):
109109 suffix = "six"
110110 _error_id_prefix = "django_mongodb_backend.indexes.SearchIndex"
111111
112- def __init__ (self , * , fields = (), name = None ):
112+ def __init__ (
113+ self , * , fields = (), field_mappings = None , name = None , analyzer = None , search_analyzer = None
114+ ):
115+ if field_mappings and not isinstance (field_mappings , dict ):
116+ raise ValueError (
117+ "field_mappings must be a dictionary mapping field names to their "
118+ "Atlas Search index options."
119+ )
120+ if analyzer and not isinstance (analyzer , str ):
121+ raise ValueError (f"analyzer must be a string; got: { type (analyzer )} ." )
122+ if search_analyzer and not isinstance (search_analyzer , str ):
123+ raise ValueError (f"search_analyzer must be a string; got: { type (search_analyzer )} ." )
124+ self .field_mappings = field_mappings
125+ self .analyzer = analyzer
126+ self .search_analyzer = search_analyzer
127+ if field_mappings :
128+ if fields :
129+ raise ValueError ("Cannot provide fields and field_mappings." )
130+ fields = [* self .field_mappings .keys ()]
113131 super ().__init__ (fields = fields , name = name )
114132
133+ def deconstruct (self ):
134+ path , args , kwargs = super ().deconstruct ()
135+ if self .field_mappings :
136+ kwargs ["field_mappings" ] = self .field_mappings
137+ del kwargs ["fields" ]
138+ if self .analyzer :
139+ kwargs ["analyzer" ] = self .analyzer
140+ if self .search_analyzer :
141+ kwargs ["search_analyzer" ] = self .search_analyzer
142+ return path , args , kwargs
143+
115144 def check (self , model , connection ):
116145 errors = []
117146 if not connection .features .supports_atlas_search :
@@ -152,12 +181,21 @@ def get_pymongo_index_model(
152181 return None
153182 fields = {}
154183 for field_name , _ in self .fields_orders :
155- field = model ._meta .get_field (field_name )
156- type_ = self .search_index_data_types (field .db_type (schema_editor .connection ))
157184 field_path = column_prefix + model ._meta .get_field (field_name ).column
158- fields [field_path ] = {"type" : type_ }
185+ if self .field_mappings :
186+ fields [field_path ] = self .field_mappings [field_name ]
187+ else :
188+ field = model ._meta .get_field (field_name )
189+ type_ = self .search_index_data_types (field .db_type (schema_editor .connection ))
190+ fields [field_path ] = {"type" : type_ }
191+ extra = {}
192+ if self .analyzer :
193+ extra ["analyzer" ] = self .analyzer
194+ if self .search_analyzer :
195+ extra ["searchAnalyzer" ] = self .search_analyzer
159196 return SearchIndexModel (
160- definition = {"mappings" : {"dynamic" : False , "fields" : fields }}, name = self .name
197+ definition = {"mappings" : {"dynamic" : False , "fields" : fields }, ** extra },
198+ name = self .name ,
161199 )
162200
163201
0 commit comments