fix(vector_stores/opensearch): honor all filter keys instead of a hardcoded identity-key list (#6454)

Co-authored-by: kartik-mem0 <kartik.labhshetwar@mem0.ai>
This commit is contained in:
microbluey
2026-07-23 00:24:16 +05:30
committed by GitHub
co-authored by kartik-mem0
parent a9cb4bb644
commit a58e0586ad
2 changed files with 78 additions and 21 deletions
+19 -21
View File
@@ -16,6 +16,7 @@ from mem0.vector_stores.base import VectorStoreBase
logger = logging.getLogger(__name__)
_SAFE_FILTER_KEY = re.compile(r"^[a-zA-Z_][a-zA-Z0-9_.]*$")
_IDENTITY_FILTER_KEYS = ("user_id", "agent_id", "run_id")
def _validate_filter(key: str, value) -> None:
@@ -28,6 +29,21 @@ def _validate_filter(key: str, value) -> None:
)
def _build_filter_clauses(filters):
"""Build term clauses from every filter key, not just the identity keys."""
filter_clauses = []
for key, value in (filters or {}).items():
if value is None:
continue
if key not in _IDENTITY_FILTER_KEYS and (not isinstance(value, (str, int, float, bool)) or value == "*"):
logger.debug(f"Ignoring non-scalar or wildcard filter value for key {key!r}")
continue
_validate_filter(key, value)
field = f"payload.{key}.keyword" if isinstance(value, str) else f"payload.{key}"
filter_clauses.append({"term": {field: value}})
return filter_clauses
class OutputData(BaseModel):
id: str
score: float
@@ -204,13 +220,7 @@ class OpenSearchDB(VectorStoreBase):
query_body = {"size": top_k * 2, "query": None}
# Prepare filter conditions if applicable
filter_clauses = []
if filters:
for key in ["user_id", "run_id", "agent_id"]:
value = filters.get(key)
if value:
_validate_filter(key, value)
filter_clauses.append({"term": {f"payload.{key}.keyword": value}})
filter_clauses = _build_filter_clauses(filters)
# Combine knn with filters if needed
if filter_clauses:
@@ -255,13 +265,7 @@ class OpenSearchDB(VectorStoreBase):
}
# Apply filters consistently with the existing search() method
filter_clauses = []
if filters:
for key in ["user_id", "run_id", "agent_id"]:
value = filters.get(key)
if value:
_validate_filter(key, value)
filter_clauses.append({"term": {f"payload.{key}.keyword": value}})
filter_clauses = _build_filter_clauses(filters)
if filter_clauses:
bool_query["filter"] = filter_clauses
@@ -370,13 +374,7 @@ class OpenSearchDB(VectorStoreBase):
"""List all memories with optional filters."""
query: Dict = {"query": {"match_all": {}}}
filter_clauses = []
if filters:
for key in ["user_id", "run_id", "agent_id"]:
value = filters.get(key)
if value:
_validate_filter(key, value)
filter_clauses.append({"term": {f"payload.{key}.keyword": value}})
filter_clauses = _build_filter_clauses(filters)
if filter_clauses:
query["query"] = {"bool": {"filter": filter_clauses}}