fix: ensure all metadata filters are processed in AND logic (#13019)

### 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 <Clint-chan@users.noreply.github.com>
This commit is contained in:
Clint-chan
2026-02-06 12:57:27 +08:00
committed by GitHub
parent 0586d5148d
commit a68c56def7

View File

@ -138,20 +138,24 @@ def meta_filter(metas: dict, filters: list[dict], logic: str = "and"):
ids.extend(docids) ids.extend(docids)
return ids return ids
for k, v2docs in metas.items(): for f in filters:
for f in filters: k = f["key"]
if k != f["key"]: if k not in metas:
continue # Key not found in metas: treat as no match
ids = []
else:
v2docs = metas[k]
ids = filter_out(v2docs, f["op"], f["value"]) 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: else:
if logic == "and": doc_ids = doc_ids | set(ids)
doc_ids = doc_ids & set(ids)
if not doc_ids:
return []
else:
doc_ids = doc_ids | set(ids)
return list(doc_ids) return list(doc_ids)