@@ -61,6 +61,8 @@ class BaseFieldAttributes(BaseModel):
6161
6262 sortable : bool = Field (default = False )
6363 """Enable faster result sorting on the field at runtime"""
64+ index_missing : bool = Field (default = False )
65+ """Allow indexing and searching for missing values (documents without the field)"""
6466
6567
6668class TextFieldAttributes (BaseFieldAttributes ):
@@ -74,6 +76,8 @@ class TextFieldAttributes(BaseFieldAttributes):
7476 """Keep a suffix trie with all terms which match the suffix to optimize certain queries"""
7577 phonetic_matcher : Optional [str ] = None
7678 """Used to perform phonetic matching during search"""
79+ index_empty : bool = Field (default = False )
80+ """Allow indexing and searching for empty strings"""
7781
7882
7983class TagFieldAttributes (BaseFieldAttributes ):
@@ -85,6 +89,8 @@ class TagFieldAttributes(BaseFieldAttributes):
8589 """Treat text as case sensitive or not. By default, tag characters are converted to lowercase"""
8690 withsuffixtrie : bool = Field (default = False )
8791 """Keep a suffix trie with all terms which match the suffix to optimize certain queries"""
92+ index_empty : bool = Field (default = False )
93+ """Allow indexing and searching for empty strings"""
8894
8995
9096class NumericFieldAttributes (BaseFieldAttributes ):
@@ -112,6 +118,8 @@ class BaseVectorFieldAttributes(BaseModel):
112118 """The distance metric used to measure query relevance"""
113119 initial_cap : Optional [int ] = None
114120 """Initial vector capacity in the index affecting memory allocation size of the index"""
121+ index_missing : bool = Field (default = False )
122+ """Allow indexing and searching for missing values (documents without the field)"""
115123
116124 @field_validator ("algorithm" , "datatype" , "distance_metric" , mode = "before" )
117125 @classmethod
@@ -129,6 +137,8 @@ def field_data(self) -> Dict[str, Any]:
129137 }
130138 if self .initial_cap is not None : # Only include it if it's set
131139 field_data ["INITIAL_CAP" ] = self .initial_cap
140+ if self .index_missing : # Only include it if it's set
141+ field_data ["INDEXMISSING" ] = True
132142 return field_data
133143
134144
@@ -190,14 +200,30 @@ class TextField(BaseField):
190200
191201 def as_redis_field (self ) -> RedisField :
192202 name , as_name = self ._handle_names ()
193- return RedisTextField (
194- name ,
195- as_name = as_name ,
196- weight = self .attrs .weight , # type: ignore
197- no_stem = self .attrs .no_stem , # type: ignore
198- phonetic_matcher = self .attrs .phonetic_matcher , # type: ignore
199- sortable = self .attrs .sortable ,
200- )
203+ # Build arguments for RedisTextField
204+ kwargs : Dict [str , Any ] = {
205+ "weight" : self .attrs .weight , # type: ignore
206+ "no_stem" : self .attrs .no_stem , # type: ignore
207+ "sortable" : self .attrs .sortable ,
208+ }
209+
210+ # Only add as_name if it's not None
211+ if as_name is not None :
212+ kwargs ["as_name" ] = as_name
213+
214+ # Only add phonetic_matcher if it's not None
215+ if self .attrs .phonetic_matcher is not None : # type: ignore
216+ kwargs ["phonetic_matcher" ] = self .attrs .phonetic_matcher # type: ignore
217+
218+ # Add INDEXMISSING if enabled
219+ if self .attrs .index_missing : # type: ignore
220+ kwargs ["index_missing" ] = True
221+
222+ # Add INDEXEMPTY if enabled
223+ if self .attrs .index_empty : # type: ignore
224+ kwargs ["index_empty" ] = True
225+
226+ return RedisTextField (name , ** kwargs )
201227
202228
203229class TagField (BaseField ):
@@ -208,13 +234,26 @@ class TagField(BaseField):
208234
209235 def as_redis_field (self ) -> RedisField :
210236 name , as_name = self ._handle_names ()
211- return RedisTagField (
212- name ,
213- as_name = as_name ,
214- separator = self .attrs .separator , # type: ignore
215- case_sensitive = self .attrs .case_sensitive , # type: ignore
216- sortable = self .attrs .sortable ,
217- )
237+ # Build arguments for RedisTagField
238+ kwargs : Dict [str , Any ] = {
239+ "separator" : self .attrs .separator , # type: ignore
240+ "case_sensitive" : self .attrs .case_sensitive , # type: ignore
241+ "sortable" : self .attrs .sortable ,
242+ }
243+
244+ # Only add as_name if it's not None
245+ if as_name is not None :
246+ kwargs ["as_name" ] = as_name
247+
248+ # Add INDEXMISSING if enabled
249+ if self .attrs .index_missing : # type: ignore
250+ kwargs ["index_missing" ] = True
251+
252+ # Add INDEXEMPTY if enabled
253+ if self .attrs .index_empty : # type: ignore
254+ kwargs ["index_empty" ] = True
255+
256+ return RedisTagField (name , ** kwargs )
218257
219258
220259class NumericField (BaseField ):
@@ -225,11 +264,20 @@ class NumericField(BaseField):
225264
226265 def as_redis_field (self ) -> RedisField :
227266 name , as_name = self ._handle_names ()
228- return RedisNumericField (
229- name ,
230- as_name = as_name ,
231- sortable = self .attrs .sortable ,
232- )
267+ # Build arguments for RedisNumericField
268+ kwargs : Dict [str , Any ] = {
269+ "sortable" : self .attrs .sortable ,
270+ }
271+
272+ # Only add as_name if it's not None
273+ if as_name is not None :
274+ kwargs ["as_name" ] = as_name
275+
276+ # Add INDEXMISSING if enabled
277+ if self .attrs .index_missing : # type: ignore
278+ kwargs ["index_missing" ] = True
279+
280+ return RedisNumericField (name , ** kwargs )
233281
234282
235283class GeoField (BaseField ):
@@ -240,11 +288,20 @@ class GeoField(BaseField):
240288
241289 def as_redis_field (self ) -> RedisField :
242290 name , as_name = self ._handle_names ()
243- return RedisGeoField (
244- name ,
245- as_name = as_name ,
246- sortable = self .attrs .sortable ,
247- )
291+ # Build arguments for RedisGeoField
292+ kwargs : Dict [str , Any ] = {
293+ "sortable" : self .attrs .sortable ,
294+ }
295+
296+ # Only add as_name if it's not None
297+ if as_name is not None :
298+ kwargs ["as_name" ] = as_name
299+
300+ # Add INDEXMISSING if enabled
301+ if self .attrs .index_missing : # type: ignore
302+ kwargs ["index_missing" ] = True
303+
304+ return RedisGeoField (name , ** kwargs )
248305
249306
250307class FlatVectorField (BaseField ):
0 commit comments