1+ from typing import List
2+
3+ from redis import DataError
4+
5+
16class Field :
27
38 NUMERIC = "NUMERIC"
49 TEXT = "TEXT"
510 WEIGHT = "WEIGHT"
611 GEO = "GEO"
712 TAG = "TAG"
13+ VECTOR = "VECTOR"
814 SORTABLE = "SORTABLE"
915 NOINDEX = "NOINDEX"
1016 AS = "AS"
1117
12- def __init__ (self , name , args = [], sortable = False , no_index = False , as_name = None ):
18+ def __init__ (
19+ self ,
20+ name : str ,
21+ args : List [str ] = None ,
22+ sortable : bool = False ,
23+ no_index : bool = False ,
24+ as_name : str = None ,
25+ ):
26+ if args is None :
27+ args = []
1328 self .name = name
1429 self .args = args
1530 self .args_suffix = list ()
@@ -44,7 +59,12 @@ class TextField(Field):
4459 PHONETIC = "PHONETIC"
4560
4661 def __init__ (
47- self , name , weight = 1.0 , no_stem = False , phonetic_matcher = None , ** kwargs
62+ self ,
63+ name : str ,
64+ weight : float = 1.0 ,
65+ no_stem : bool = False ,
66+ phonetic_matcher : str = None ,
67+ ** kwargs ,
4868 ):
4969 Field .__init__ (self , name , args = [Field .TEXT , Field .WEIGHT , weight ], ** kwargs )
5070
@@ -65,7 +85,7 @@ class NumericField(Field):
6585 NumericField is used to define a numeric field in a schema definition
6686 """
6787
68- def __init__ (self , name , ** kwargs ):
88+ def __init__ (self , name : str , ** kwargs ):
6989 Field .__init__ (self , name , args = [Field .NUMERIC ], ** kwargs )
7090
7191
@@ -74,7 +94,7 @@ class GeoField(Field):
7494 GeoField is used to define a geo-indexing field in a schema definition
7595 """
7696
77- def __init__ (self , name , ** kwargs ):
97+ def __init__ (self , name : str , ** kwargs ):
7898 Field .__init__ (self , name , args = [Field .GEO ], ** kwargs )
7999
80100
@@ -86,7 +106,52 @@ class TagField(Field):
86106
87107 SEPARATOR = "SEPARATOR"
88108
89- def __init__ (self , name , separator = "," , ** kwargs ):
109+ def __init__ (self , name : str , separator : str = "," , ** kwargs ):
90110 Field .__init__ (
91111 self , name , args = [Field .TAG , self .SEPARATOR , separator ], ** kwargs
92112 )
113+
114+
115+ class VectorField (Field ):
116+ """
117+ Allows vector similarity queries against the value in this attribute.
118+ See https://oss.redis.com/redisearch/Vectors/#vector_fields.
119+ """
120+
121+ def __init__ (self , name : str , algorithm : str , attributes : dict , ** kwargs ):
122+ """
123+ Create Vector Field. Notice that Vector cannot have sortable or no_index tag,
124+ although it's also a Field.
125+
126+ ``name`` is the name of the field.
127+
128+ ``algorithm`` can be "FLAT" or "HNSW".
129+
130+ ``attributes`` each algorithm can have specific attributes. Some of them
131+ are mandatory and some of them are optional. See
132+ https://oss.redis.com/redisearch/master/Vectors/#specific_creation_attributes_per_algorithm
133+ for more information.
134+ """
135+ sort = kwargs .get ("sortable" , False )
136+ noindex = kwargs .get ("no_index" , False )
137+
138+ if sort or noindex :
139+ raise DataError ("Cannot set 'sortable' or 'no_index' in Vector fields." )
140+
141+ if algorithm .upper () not in ["FLAT" , "HNSW" ]:
142+ raise DataError (
143+ "Realtime vector indexing supporting 2 Indexing Methods:"
144+ "'FLAT' and 'HNSW'."
145+ )
146+
147+ attr_li = []
148+
149+ for key , value in attributes .items ():
150+ attr_li .extend ([key , value ])
151+
152+ Field .__init__ (
153+ self ,
154+ name ,
155+ args = [Field .VECTOR , algorithm , len (attr_li ), * attr_li ],
156+ ** kwargs ,
157+ )
0 commit comments