21
21
QueryNotSupportedError ,
22
22
RedisModelError ,
23
23
FindQuery ,
24
+ HashModel
24
25
)
25
26
26
27
# We need to run this check as sync code (during tests) even in async mode
@@ -120,7 +121,7 @@ async def members(address, m):
120
121
age = 34 ,
121
122
join_date = today ,
122
123
address = address ,
123
- bio = "Kim does not work in tech " ,
124
+ bio = "Kim is a newer hire " ,
124
125
)
125
126
126
127
member3 = m .Member (
@@ -142,18 +143,21 @@ async def members(address, m):
142
143
143
144
@py_test_mark_asyncio
144
145
async def test_find_query_in (members , m ):
146
+ # << means "in"
145
147
member1 , member2 , member3 = members
146
148
model_name , fq = await FindQuery (expressions = [m .Member .pk << [member1 .pk , member2 .pk , member3 .pk ]], model = m .Member ).get_query ()
147
149
in_str = "(@pk:{" + str (member1 .pk ) + "|" + str (member2 .pk ) + "|" + str (member3 .pk ) + "})"
148
150
assert fq == ['FT.SEARCH' , model_name , in_str , 'LIMIT' , 0 , 1000 ]
149
151
150
152
@py_test_mark_asyncio
151
153
async def test_find_query_not_in (members , m ):
154
+ # >> means "not in"
152
155
member1 , member2 , member3 = members
153
156
model_name , fq = await FindQuery (expressions = [m .Member .pk >> [member2 .pk , member3 .pk ]], model = m .Member ).get_query ()
154
157
not_in_str = "-(@pk:{" + str (member2 .pk ) + "|" + str (member3 .pk ) + "})"
155
158
assert fq == ['FT.SEARCH' , model_name , not_in_str , 'LIMIT' , 0 , 1000 ]
156
159
160
+ # experssion testing; (==, !=, <, <=, >, >=, |, &, ~)
157
161
@py_test_mark_asyncio
158
162
async def test_find_query_eq (m ):
159
163
model_name , fq = await FindQuery (expressions = [m .Member .first_name == "Andrew" ], model = m .Member ).get_query ()
@@ -184,6 +188,7 @@ async def test_find_query_ge(m):
184
188
model_name , fq = await FindQuery (expressions = [m .Member .age >= 38 ], model = m .Member ).get_query ()
185
189
assert fq == ['FT.SEARCH' , model_name , '@age:[38 +inf]' , 'LIMIT' , 0 , 1000 ]
186
190
191
+ # tests for sorting and text search with and, or, not
187
192
@py_test_mark_asyncio
188
193
async def test_find_query_sort (m ):
189
194
model_name , fq = await FindQuery (expressions = [m .Member .age > 0 ], model = m .Member , sort_fields = ["age" ]).get_query ()
@@ -229,6 +234,7 @@ async def test_find_query_text_search_not_or_and(m, members):
229
234
model_name , fq = await FindQuery (expressions = [~ (((m .Member .first_name == "Andrew" ) | (m .Member .age < 40 )) & (m .Member .last_name == "Brookins" ))], model = m .Member ).get_query ()
230
235
assert fq == ['FT.SEARCH' , model_name , '-(((@first_name:{Andrew})| (@age:[-inf (40])) (@last_name:{Brookins}))' , 'LIMIT' , 0 , 1000 ]
231
236
237
+ # text search operators; contains, startswith, endswith, fuzzy
232
238
@py_test_mark_asyncio
233
239
async def test_find_query_text_contains (m ):
234
240
model_name , fq = await FindQuery (expressions = [m .Member .first_name .contains ("drew" )], model = m .Member ).get_query ()
@@ -242,4 +248,34 @@ async def test_find_query_text_startswith(m):
242
248
@py_test_mark_asyncio
243
249
async def test_find_query_text_endswith (m ):
244
250
model_name , fq = await FindQuery (expressions = [m .Member .first_name .endswith ("ew" )], model = m .Member ).get_query ()
245
- assert fq == ['FT.SEARCH' , model_name , '(@first_name:{*ew})' , 'LIMIT' , 0 , 1000 ]
251
+ assert fq == ['FT.SEARCH' , model_name , '(@first_name:{*ew})' , 'LIMIT' , 0 , 1000 ]
252
+
253
+ @py_test_mark_asyncio
254
+ async def test_find_query_test_fuzzy (m ):
255
+ model_name , fq = await FindQuery (expressions = [m .Member .bio % '%newb%' ], model = m .Member ).get_query ()
256
+ assert fq == ['FT.SEARCH' , model_name , '@bio_fts:%newb%' , 'LIMIT' , 0 , 1000 ]
257
+
258
+ # limit, offset, page_size
259
+ @py_test_mark_asyncio
260
+ async def test_find_query_limit_one (m ):
261
+ model_name , fq = await FindQuery (expressions = [m .Member .first_name == "Andrew" ], model = m .Member , limit = 1 ).get_query ()
262
+ assert fq == ['FT.SEARCH' , model_name , '@first_name:{Andrew}' , 'LIMIT' , 0 , 1 ]
263
+
264
+ @py_test_mark_asyncio
265
+ async def test_find_query_limit_offset (m ):
266
+ model_name , fq = await FindQuery (expressions = [m .Member .first_name == "Andrew" ], model = m .Member , limit = 1 , offset = 1 ).get_query ()
267
+ assert fq == ['FT.SEARCH' , model_name , '@first_name:{Andrew}' , 'LIMIT' , 1 , 1 ]
268
+
269
+ @py_test_mark_asyncio
270
+ async def test_find_query_page_size (m ):
271
+ # note that this test in unintuitive.
272
+ # page_size gets resolved in a while True loop that makes copies of the intial query and adds the limit and offset each time
273
+ model_name , fq = await FindQuery (expressions = [m .Member .first_name == "Andrew" ], model = m .Member , page_size = 1 ).get_query ()
274
+ assert fq == ['FT.SEARCH' , model_name , '@first_name:{Andrew}' , 'LIMIT' , 0 , 1000 ]
275
+
276
+ @py_test_mark_asyncio
277
+ async def test_find_query_monster (m ):
278
+ # test monster query with everything everywhere all at once
279
+ # including ors, nots, ands, less thans, greater thans, text search
280
+ model_name , fq = await FindQuery (expressions = [~ (((m .Member .first_name == "Andrew" ) | (m .Member .age < 40 )) & ((m .Member .last_name .contains ("oo" ) | ~ (m .Member .email .startswith ("z" )))))], model = m .Member , limit = 1 , offset = 1 ).get_query ()
281
+ assert fq == ['FT.SEARCH' , model_name , '-(((@first_name:{Andrew})| (@age:[-inf (40])) (((@last_name:{*oo*}))| -((@email:{z*}))))' , 'LIMIT' , 1 , 1 ]
0 commit comments