{"record":{"id":"08a5319f5210887a","repo":"MemPalace/mempalace","slug":"operator-op-r-not-supported-by-milvus","errorCode":null,"errorMessage":"operator {op!r} not supported by milvus","messagePattern":"operator (.+?) not supported by milvus","errorType":"exception","errorClass":"UnsupportedFilterError","httpStatus":null,"severity":"error","filePath":"mempalace/backends/milvus.py","lineNumber":139,"sourceCode":"                items = \", \".join(_quote_value(item) for item in operand)\n                parts.append(f\"{field} in [{items}]\")\n            elif op == \"$nin\":\n                if not isinstance(operand, list) or not operand:\n                    raise UnsupportedFilterError(f\"$nin requires a non-empty list for {field!r}\")\n                items = \", \".join(_quote_value(item) for item in operand)\n                parts.append(f\"{field} not in [{items}]\")\n            elif op == \"$gt\":\n                parts.append(f\"{field} > {_quote_value(operand)}\")\n            elif op == \"$gte\":\n                parts.append(f\"{field} >= {_quote_value(operand)}\")\n            elif op == \"$lt\":\n                parts.append(f\"{field} < {_quote_value(operand)}\")\n            elif op == \"$lte\":\n                parts.append(f\"{field} <= {_quote_value(operand)}\")\n            elif op == \"$contains\":\n                parts.append(f\"{field} like {_like_value(operand)}\")\n            else:\n                raise UnsupportedFilterError(f\"operator {op!r} not supported by milvus\")\n        return \" and \".join(parts)\n    return f\"{field} == {_quote_value(expected)}\"\n\n\ndef _translate_clause(clause: dict) -> str:\n    if not isinstance(clause, dict):\n        raise UnsupportedFilterError(f\"where clause must be a dict, got {type(clause).__name__}\")\n    if not clause:\n        return \"\"\n    parts = []\n    for key, value in clause.items():\n        if key == \"$and\":\n            if not isinstance(value, list) or not value:\n                raise UnsupportedFilterError(\"$and requires a non-empty list of clauses\")\n            nested = [_translate_clause(item) for item in value]\n            parts.append(\"(\" + \" and \".join(part for part in nested if part) + \")\")\n        elif key == \"$or\":\n            if not isinstance(value, list) or not value:","sourceCodeStart":121,"sourceCodeEnd":157,"githubUrl":"https://github.com/MemPalace/mempalace/blob/06cb6987f02610784fefbad4b2bd5d026d164ba6/mempalace/backends/milvus.py#L121-L157","documentation":"Raised in _translate_field() when a field's operator dict contains a key other than the supported set ($eq, $ne, $in, $nin, $gt, $gte, $lt, $lte, $contains). The Milvus backend only implements this portable subset of the metadata DSL; unknown operators are rejected with UnsupportedFilterError during translation so no invalid filter string reaches the server.","triggerScenarios":"where={\"age\": {\"$exists\": True}}, {\"name\": {\"$regex\": \"^a\"}}, {\"ts\": {\"$between\": [1, 2]}}, or any Mongo-style operator ($and/$or excluded — those are handled at clause level) unsupported here.","commonSituations":"Porting MongoDB or ChromaDB where-clauses that use richer operators; sharing filter builders across backends without trimming to the supported subset.","solutions":["Replace $regex with $contains (translated to Milvus 'like') where substring semantics suffice","Replace $exists/$type checks by filtering on a stored sentinel value instead","Express ranges with $gte/$lt combinations","Run per-backend capability checks before building the clause"],"exampleFix":"// before\nwhere = {\"note\": {\"$regex\": \"palace\"}}\n\n// after\nwhere = {\"note\": {\"$contains\": \"palace\"}}","handlingStrategy":"validation","validationCode":"SUPPORTED_OPS = {\"$eq\", \"$ne\", \"$in\", \"$nin\", \"$gt\", \"$gte\", \"$lt\", \"$lte\", \"$contains\"}\n\ndef uses_supported_operators(where: dict) -> bool:\n    for v in where.values():\n        if isinstance(v, dict):\n            for op in v:\n                if op not in SUPPORTED_OPS:\n                    return False\n    return True","typeGuard":null,"tryCatchPattern":"from mempalace.backends.base import UnsupportedFilterError\ntry:\n    collection.query(query_texts=[q], where=where, n_results=k)\nexcept UnsupportedFilterError as e:\n    raise ValueError(f\"rewrite filter for milvus backend: {e}\") from e","preventionTips":["Keep a per-backend operator capability table in shared filter code","Replace $regex with $contains at authoring time","Add integration tests per backend for every operator you use"],"tags":["milvus","filter","unsupported-operator","dsl"],"backgroundTag":null,"analyzedSha":"06cb6987f02610784fefbad4b2bd5d026d164ba6","analyzedAt":"2026-08-15T03:03:36.213Z","schemaVersion":2},"datasetVersion":"2026-08-15T22:17:37.221Z"}