From a68c56def7b38155d49f8a412c8c711c32afac45 Mon Sep 17 00:00:00 2001 From: Clint-chan <62379027+Clint-chan@users.noreply.github.com> Date: Fri, 6 Feb 2026 12:57:27 +0800 Subject: [PATCH] fix: ensure all metadata filters are processed in AND logic (#13019) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit ### What problem does this PR solve? Bug: When a filter key doesn't exist in metas or has no matching values, the filter was skipped entirely, causing AND logic to fail. Example: - Filter 1: meeting_series = '宏观早8点' (matches doc1, doc2, doc3) - Filter 2: date = '2026-03-05' (no matches) - Expected: [] (AND should return empty) - Actual: [doc1, doc2, doc3] (Filter 2 was skipped) Root cause: Old logic iterated metas.items() first, then filters. If a filter's key wasn't in metas, it was never processed. Fix: Iterate filters first, then look up in metas. If key not found, treat as no match (empty result), which correctly applies AND logic. Changes: - Changed loop order from 'for k in metas: for f in filters' to 'for f in filters: if f.key in metas' - Explicitly handle missing keys as empty results ### Type of change - [x] Bug Fix (non-breaking change which fixes an issue) Co-authored-by: Clint-chan --- common/metadata_utils.py | 28 ++++++++++++++++------------ 1 file changed, 16 insertions(+), 12 deletions(-) diff --git a/common/metadata_utils.py b/common/metadata_utils.py index 8403dd9e0..c919bd186 100644 --- a/common/metadata_utils.py +++ b/common/metadata_utils.py @@ -138,20 +138,24 @@ def meta_filter(metas: dict, filters: list[dict], logic: str = "and"): ids.extend(docids) return ids - for k, v2docs in metas.items(): - for f in filters: - if k != f["key"]: - continue + for f in filters: + k = f["key"] + if k not in metas: + # Key not found in metas: treat as no match + ids = [] + else: + v2docs = metas[k] ids = filter_out(v2docs, f["op"], f["value"]) - if not doc_ids: - doc_ids = set(ids) + + if not doc_ids: + doc_ids = set(ids) + else: + if logic == "and": + doc_ids = doc_ids & set(ids) + if not doc_ids: + return [] else: - if logic == "and": - doc_ids = doc_ids & set(ids) - if not doc_ids: - return [] - else: - doc_ids = doc_ids | set(ids) + doc_ids = doc_ids | set(ids) return list(doc_ids)