From c36c042bac8edf134f396af716960f4e24d9b9d2 Mon Sep 17 00:00:00 2001 From: Wenqiang Wei <46308778+endxxxx@users.noreply.github.com> Date: Wed, 11 Feb 2026 10:52:46 +0800 Subject: [PATCH 1/2] fix: support cases when there is both field condition and logical operators --- src/memos/vec_dbs/milvus.py | 33 +++++++++++++++++++++++++-------- 1 file changed, 25 insertions(+), 8 deletions(-) diff --git a/src/memos/vec_dbs/milvus.py b/src/memos/vec_dbs/milvus.py index cc8909d34..3963e6e4a 100644 --- a/src/memos/vec_dbs/milvus.py +++ b/src/memos/vec_dbs/milvus.py @@ -287,16 +287,33 @@ def _dict_to_expr(self, filter_dict: dict[str, Any]) -> str: def _build_expression(self, condition: Any) -> str: """Build expression from condition dict or value.""" if isinstance(condition, dict): + conditions = [] + # Handle logical operators if "and" in condition: - return self._handle_logical_and(condition["and"]) - elif "or" in condition: - return self._handle_logical_or(condition["or"]) - elif "not" in condition: - return self._handle_logical_not(condition["not"]) - else: - # Handle field conditions - return self._handle_field_conditions(condition) + and_expr = self._handle_logical_and(condition["and"]) + if and_expr: + conditions.append(and_expr) + if "or" in condition: + or_expr = self._handle_logical_or(condition["or"]) + if or_expr: + conditions.append(or_expr) + if "not" in condition: + not_expr = self._handle_logical_not(condition["not"]) + if not_expr: + conditions.append(not_expr) + + # Handle field conditions (keys that are not logical operators) + field_dict = {k: v for k, v in condition.items() if k not in ["and", "or", "not"]} + if field_dict: + field_expr = self._handle_field_conditions(field_dict) + if field_expr: + conditions.append(field_expr) + + # Combine all conditions with AND + if not conditions: + return "" + return " and ".join(conditions) else: # Simple value comparison return f"{condition}" From 93e520007fee1fce47f09678bf52a85a4cf72062 Mon Sep 17 00:00:00 2001 From: Wenqiang Wei <46308778+endxxxx@users.noreply.github.com> Date: Wed, 11 Feb 2026 16:48:04 +0800 Subject: [PATCH 2/2] fix: support hours, minutes, and seconds to the filter field. --- src/memos/vec_dbs/milvus.py | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) diff --git a/src/memos/vec_dbs/milvus.py b/src/memos/vec_dbs/milvus.py index 3963e6e4a..e63cabf6f 100644 --- a/src/memos/vec_dbs/milvus.py +++ b/src/memos/vec_dbs/milvus.py @@ -363,6 +363,16 @@ def _handle_field_conditions(self, condition_dict: dict[str, Any]) -> str: def _build_field_expression(self, field: str, value: Any) -> str: """Build expression for a single field.""" + # Convert date-time format from 'YYYY-MM-DD HH:MM:SS' to 'YYYY-MM-DDTHH:MM:SS' for comparison + if (field == "created_at" or field == "updated_at") and isinstance(value, str): + # Replace space with 'T' to match ISO 8601 format + value = value.replace(" ", "T") + elif (field == "created_at" or field == "updated_at") and isinstance(value, dict): + # Handle dict case (e.g., {"gte": "2026-02-09 15:43:12"}) + for op, operand in value.items(): + if isinstance(operand, str): + value[op] = operand.replace(" ", "T") + # Handle comparison operators if isinstance(value, dict): if len(value) == 1: @@ -435,6 +445,11 @@ def _handle_comparison_operator(self, field: str, operator: str, value: Any) -> """Handle comparison operators (gte, lte, gt, lt, ne).""" milvus_op = {"gte": ">=", "lte": "<=", "gt": ">", "lt": "<", "ne": "!="}.get(operator, "==") + # Convert date-time format from 'YYYY-MM-DD HH:MM:SS' to 'YYYY-MM-DDTHH:MM:SS' for comparison + if (field == "created_at" or field == "updated_at") and isinstance(value, str): + # Replace space with 'T' to match ISO 8601 format + value = value.replace(" ", "T") + formatted_value = self._format_value(value) return f"payload['{field}'] {milvus_op} {formatted_value}" @@ -520,7 +535,9 @@ def get_by_filter( Returns: List of items including vectors and payload that match the filter """ + logger.info(f"filter for milvus: {filter}") expr = self._dict_to_expr(filter) if filter else "" + logger.info(f"filter expr for milvus: {expr}") all_items = [] # Use query_iterator for efficient pagination