-
Notifications
You must be signed in to change notification settings - Fork 5.2k
Description
π Describe the bug
Enhanced Metadata Filtering Not Working with Qdrant Backend
Summary
The enhanced metadata filtering operators documented at https://docs.mem0.ai/open-source/features/metadata-filtering do not work with the Qdrant vector store backend. All operators except simple scalar equality matching fail with ValidationError.
Environment
- mem0 version: 1.0.3
- qdrant-client version: 1.16.2
- Qdrant server version: latest (Docker)
- Python version: 3.11+
- OS: Linux
Problem Description
According to the Enhanced Metadata Filtering documentation, Mem0 1.0.0+ should support the following operators:
- Comparison operators:
eq,ne,gt,gte,lt,lte - List operators:
in,nin - String operators:
contains,icontains - Wildcard:
* - Logical operators:
AND,OR,NOT
The documentation also states that Qdrant supports "Full comparison, list, and logical support. Handles deeply nested boolean logic efficiently."
However, in practice, only simple scalar equality matching works. All other operators fail with Pydantic ValidationError.
Steps to Reproduce
from mem0 import Memory
# Configure with Qdrant backend
config = {
"vector_store": {
"provider": "qdrant",
"config": {
"host": "localhost",
"port": 6333,
"collection_name": "test_collection",
}
},
# ... LLM and embedder config
}
m = Memory.from_config(config)
# Add test memory
m.add(
messages=[{"role": "user", "content": "Python is my favorite language"}],
user_id="test_user",
metadata={"category": "programming", "priority": 10}
)
# This WORKS - simple scalar matching
results = m.search(
"programming",
user_id="test_user",
filters={"category": "programming"} # β
Works
)
# This FAILS - eq operator
results = m.search(
"programming",
user_id="test_user",
filters={"category": {"eq": "programming"}} # β ValidationError
)
# This FAILS - gte operator
results = m.search(
"programming",
user_id="test_user",
filters={"priority": {"gte": 5}} # β ValidationError
)
# This FAILS - in operator
results = m.search(
"programming",
user_id="test_user",
filters={"category": {"in": ["programming", "hobby"]}} # β ValidationError
)
# This FAILS - AND operator
results = m.search(
"programming",
user_id="test_user",
filters={"AND": [{"category": "programming"}, {"priority": 10}]} # β ValidationError
)Expected Behavior
All operators documented in the Enhanced Metadata Filtering page should work with Qdrant backend, as stated in the documentation:
Qdrant: Full comparison, list, and logical support. Handles deeply nested boolean logic efficiently.
Actual Behavior
All operators except simple scalar matching fail with:
ValidationError: 3 validation errors for MatchValue
value.bool
Input should be a valid boolean [type=bool_type, input_value={'eq': 'programming'}, input_type=dict]
Test Results Summary
| Operator Type | Status | Example |
|---|---|---|
| Simple scalar match | β Works | {"category": "programming"} |
eq |
β Fails | {"category": {"eq": "programming"}} |
ne |
β Fails | {"category": {"ne": "programming"}} |
gt |
β Fails | {"priority": {"gt": 7}} |
gte |
β Fails | {"priority": {"gte": 8}} |
lt |
β Fails | {"priority": {"lt": 8}} |
lte |
β Fails | {"priority": {"lte": 7}} |
Range (gte+lte) |
β Fails | {"priority": {"gte": 5, "lte": 9}} |
in |
β Fails | {"category": {"in": ["a", "b"]}} |
nin |
β Fails | {"category": {"nin": ["a"]}} |
contains |
β Fails | {"tags": {"contains": "x"}} |
icontains |
β Fails | {"tags": {"icontains": "X"}} |
AND |
β Fails | {"AND": [{...}, {...}]} |
OR |
β Fails | {"OR": [{...}, {...}]} |
NOT |
β Fails | {"NOT": [{...}]} |
Root Cause Analysis
Looking at the error, it appears the Qdrant vector store implementation (mem0/vector_stores/qdrant.py) constructs filters using MatchValue which only accepts scalar values (bool, int, str), not dict or list structures.
The filter conversion logic doesn't seem to translate the enhanced filter operators (like {"eq": "value"} or {"gte": 5}) into Qdrant's native filter format (which does support these operations via qdrant_client.models.FieldCondition with Match, Range, etc.).
Suggested Fix
The Qdrant vector store implementation should:
- Parse the enhanced filter syntax (
eq,ne,gt,gte,lt,lte,in,nin,contains, etc.) - Convert them to Qdrant's native filter format using:
models.FieldConditionwithmodels.MatchValuefor equalitymodels.FieldConditionwithmodels.MatchAnyforinoperatormodels.FieldConditionwithmodels.Rangefor comparison operatorsmodels.Filterwithmust/should/must_notfor logical operators
Example of what the conversion should produce for Qdrant:
from qdrant_client import models
# For {"priority": {"gte": 5, "lte": 10}}
qdrant_filter = models.Filter(
must=[
models.FieldCondition(
key="priority",
range=models.Range(gte=5, lte=10)
)
]
)
# For {"category": {"in": ["programming", "hobby"]}}
qdrant_filter = models.Filter(
must=[
models.FieldCondition(
key="category",
match=models.MatchAny(any=["programming", "hobby"])
)
]
)Additional Context
- Qdrant natively supports all these filter operations - see Qdrant Filtering Documentation
- The issue is specifically in how mem0 translates the filter syntax to Qdrant's format
- This significantly limits the usefulness of metadata filtering when using Qdrant backend
Workaround
Currently, users must:
- Use only simple scalar matching:
{"field": "value"} - Perform multiple queries and merge results in application code for
in-like behavior - Implement post-query filtering in application code for complex conditions