1
+ from typing import List
2
+
3
+ from redis import DataError
4
+
5
+
1
6
class Field :
2
7
3
8
NUMERIC = "NUMERIC"
4
9
TEXT = "TEXT"
5
10
WEIGHT = "WEIGHT"
6
11
GEO = "GEO"
7
12
TAG = "TAG"
13
+ VECTOR = "VECTOR"
8
14
SORTABLE = "SORTABLE"
9
15
NOINDEX = "NOINDEX"
10
16
AS = "AS"
11
17
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 = []
13
28
self .name = name
14
29
self .args = args
15
30
self .args_suffix = list ()
@@ -44,7 +59,12 @@ class TextField(Field):
44
59
PHONETIC = "PHONETIC"
45
60
46
61
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 ,
48
68
):
49
69
Field .__init__ (self , name , args = [Field .TEXT , Field .WEIGHT , weight ], ** kwargs )
50
70
@@ -65,7 +85,7 @@ class NumericField(Field):
65
85
NumericField is used to define a numeric field in a schema definition
66
86
"""
67
87
68
- def __init__ (self , name , ** kwargs ):
88
+ def __init__ (self , name : str , ** kwargs ):
69
89
Field .__init__ (self , name , args = [Field .NUMERIC ], ** kwargs )
70
90
71
91
@@ -74,7 +94,7 @@ class GeoField(Field):
74
94
GeoField is used to define a geo-indexing field in a schema definition
75
95
"""
76
96
77
- def __init__ (self , name , ** kwargs ):
97
+ def __init__ (self , name : str , ** kwargs ):
78
98
Field .__init__ (self , name , args = [Field .GEO ], ** kwargs )
79
99
80
100
@@ -86,7 +106,52 @@ class TagField(Field):
86
106
87
107
SEPARATOR = "SEPARATOR"
88
108
89
- def __init__ (self , name , separator = "," , ** kwargs ):
109
+ def __init__ (self , name : str , separator : str = "," , ** kwargs ):
90
110
Field .__init__ (
91
111
self , name , args = [Field .TAG , self .SEPARATOR , separator ], ** kwargs
92
112
)
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