fix(qdrant): reject mixed range and non-range filter operators

Raise ValueError when a filter dict for a single field combines range
operators (gt/gte/lt/lte) with non-range operators (eq/ne/in/nin/etc),
preventing silent data loss where the non-range conditions were dropped.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
kartik-mem0
2026-03-21 18:04:10 +05:30
parent fb430b1a32
commit b53507efd3
2 changed files with 17 additions and 1 deletions
+7 -1
View File
@@ -161,9 +161,15 @@ class Qdrant(VectorStoreBase):
ops = set(value.keys())
range_ops = {"gt", "gte", "lt", "lte"}
non_range_ops = ops - range_ops
if ops & range_ops:
# Any combination of range operators: gt, gte, lt, lte
if non_range_ops:
raise ValueError(
f"Cannot mix range operators ({ops & range_ops}) with "
f"non-range operators ({non_range_ops}) for field '{key}'. "
f"Use AND to combine them as separate conditions."
)
range_kwargs = {op: value[op] for op in range_ops if op in value}
return FieldCondition(key=key, range=Range(**range_kwargs))
elif "eq" in value:
+10
View File
@@ -541,5 +541,15 @@ class TestQdrantEnhancedFilters(unittest.TestCase):
self.qdrant._build_field_condition("field", {"unknown_op": "foo"})
self.assertIn("Unsupported", str(ctx.exception))
def test_mixed_range_and_non_range_raises_error(self):
"""Mixing range ops with non-range ops should raise ValueError."""
with self.assertRaises(ValueError):
self.qdrant._build_field_condition("priority", {"gte": 5, "ne": 10})
def test_mixed_range_and_eq_raises_error(self):
"""Mixing range ops with eq should raise ValueError."""
with self.assertRaises(ValueError):
self.qdrant._build_field_condition("score", {"gt": 0.5, "eq": 1.0})
def tearDown(self):
del self.qdrant