@@ -162,7 +162,7 @@ def search_request_with_timeout(timeout):
162162 assert not search_fail .ok
163163
164164
165- def test_strict_mode_unindexed_filter_read_validation (collection_name ):
165+ def test_strict_mode_unindexed_filter_keyword_read_validation (collection_name ):
166166 def search_request_with_filter ():
167167 return request_with_validation (
168168 api = '/collections/{collection_name}/points/search' ,
@@ -217,6 +217,84 @@ def search_request_with_filter():
217217 search_request_with_filter ().raise_for_status ()
218218
219219
220+ def test_strict_mode_unindexed_filter_integer_read_validation (collection_name ):
221+ def search_request_with_filter ():
222+ return request_with_validation (
223+ api = '/collections/{collection_name}/points/search' ,
224+ method = "POST" ,
225+ path_params = {'collection_name' : collection_name },
226+ body = {
227+ "vector" : [0.2 , 0.1 , 0.9 , 0.7 ],
228+ "limit" : 3 ,
229+ "filter" : {
230+ "must" : [
231+ {
232+ "key" : "count" ,
233+ "match" : {
234+ "value" : 1
235+ }
236+ }
237+ ]
238+ },
239+ }
240+ )
241+
242+ search_request_with_filter ().raise_for_status ()
243+
244+ set_strict_mode (collection_name , {
245+ "enabled" : True ,
246+ "unindexed_filtering_retrieve" : True ,
247+ })
248+
249+ search_request_with_filter ().raise_for_status ()
250+
251+ set_strict_mode (collection_name , {
252+ "unindexed_filtering_retrieve" : False ,
253+ })
254+
255+ search_fail = search_request_with_filter ()
256+
257+ assert "count" in search_fail .json ()['status' ]['error' ]
258+ assert not search_fail .ok
259+
260+ request_with_validation (
261+ api = '/collections/{collection_name}/index' ,
262+ method = "PUT" ,
263+ path_params = {'collection_name' : collection_name },
264+ query_params = {'wait' : 'true' },
265+ body = {
266+ "field_name" : "count" ,
267+ "field_schema" : {
268+ "type" : "integer" ,
269+ "lookup" : False ,
270+ "range" : True ,
271+ }
272+ }
273+ ).raise_for_status ()
274+
275+ # the integer index does not support `lookup` on our match condition
276+ assert "count" in search_fail .json ()['status' ]['error' ]
277+ assert not search_fail .ok
278+
279+ request_with_validation (
280+ api = '/collections/{collection_name}/index' ,
281+ method = "PUT" ,
282+ path_params = {'collection_name' : collection_name },
283+ query_params = {'wait' : 'true' },
284+ body = {
285+ "field_name" : "count" ,
286+ "field_schema" : {
287+ "type" : "integer" ,
288+ "lookup" : True ,
289+ "range" : True ,
290+ }
291+ }
292+ ).raise_for_status ()
293+
294+ # We created an index with `lookup` on this field so it should work now
295+ search_request_with_filter ().raise_for_status ()
296+
297+
220298def test_strict_mode_unindexed_filter_write_validation (collection_name ):
221299 def update_request_with_filter ():
222300 return request_with_validation (
@@ -1013,7 +1091,7 @@ def upsert_points(ids: list[int]):
10131091 })
10141092
10151093 for i in range (32 ):
1016- print ( upsert_points ([3 , 4 ]).json () )
1094+ upsert_points ([3 , 4 ]).json ()
10171095
10181096 # Max limit has been reached and one of the next requests must fail. Due to cache it might not be the first call!
10191097 for i in range (32 ):
@@ -1368,6 +1446,26 @@ def query_request():
13681446 assert "discount_price" in query_fail .json ()['status' ]['error' ]
13691447 assert "formula expression" in query_fail .json ()['status' ]['error' ]
13701448
1449+ # Create index on `discount_price`
1450+ request_with_validation (
1451+ api = '/collections/{collection_name}/index' ,
1452+ method = "PUT" ,
1453+ path_params = {'collection_name' : collection_name },
1454+ query_params = {'wait' : 'true' },
1455+ body = {
1456+ "field_name" : "discount_price" ,
1457+ "field_schema" : {
1458+ "type" : "integer" ,
1459+ "lookup" : True ,
1460+ "range" : False ,
1461+ }
1462+ }
1463+ ).raise_for_status ()
1464+
1465+ # Query succeeds with the index
1466+ query_ok = query_request ()
1467+ assert query_ok .ok
1468+
13711469
13721470def test_strict_mode_read_rate_limiting_small_replenish (collection_name ):
13731471 """
0 commit comments