Skip to content

Commit aac76e0

Browse files
fix: resolve mypy typing errors in schema fields - Fix type annotations for kwargs dictionaries in field as_redis_field methods - Handle None values for as_name and phonetic_matcher parameters properly - Add explicit Dict[str, Any] type annotations to avoid mypy conflicts - Ensure only non-None values are passed to Redis field constructors
1 parent de1f937 commit aac76e0

File tree

1 file changed

+82
-25
lines changed

1 file changed

+82
-25
lines changed

redisvl/schema/fields.py

Lines changed: 82 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -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

6668
class 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

7983
class 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

9096
class 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

203229
class 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

220259
class 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

235283
class 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

250307
class FlatVectorField(BaseField):

0 commit comments

Comments
 (0)