fix: match list-valued metadata filters by item (#399)

This commit is contained in:
s4kura
2026-08-22 05:56:48 +08:00
committed by GitHub
parent cd9b9d49c0
commit 1ab584efe8
2 changed files with 16 additions and 7 deletions
@@ -169,13 +169,15 @@ class MetadataFilterEngine:
"""Check if field value is in the expected list/collection."""
if not isinstance(expected_value, (list, tuple, set)):
raise ValueError("'in' operator requires a list, tuple, or set")
if isinstance(field_value, (list, tuple, set)):
return any(item in expected_value for item in field_value)
return field_value in expected_value
def _not_in(self, field_value: Any, expected_value: Any) -> bool:
"""Check if field value is not in the expected list/collection."""
if not isinstance(expected_value, (list, tuple, set)):
raise ValueError("'not_in' operator requires a list, tuple, or set")
return field_value not in expected_value
return not self._in(field_value, expected_value)
# String operators
def _contains(self, field_value: Any, expected_value: Any) -> bool:
+13 -6
View File
@@ -254,14 +254,21 @@ class TestMetadataFilterEngine:
assert "doc1" in ids
assert "doc5" in ids
def test_list_membership_with_nested_tags(self):
"""Test membership operations with list metadata."""
# Note: This tests the metadata structure, not list field filtering
# For list field filtering, we'd need to modify the test data
filters = {"character": {"in": ["Alice"]}}
def test_in_filter_matches_any_list_item(self):
"""Test that in matches when any list metadata item is allowed."""
filters = {"tags": {"in": ["adventure"]}}
result = self.engine.apply_filters(self.sample_results, filters)
assert len(result) == 2
assert all(r["metadata"]["character"] == "Alice" for r in result)
assert [r["id"] for r in result] == ["doc1", "doc4"]
def test_not_in_filter_rejects_any_matching_list_item(self):
"""Test that not_in rejects list metadata containing a denied item."""
filters = {"tags": {"not_in": ["adventure"]}}
result = self.engine.apply_filters(self.sample_results, filters)
assert len(result) == 2
assert [r["id"] for r in result] == ["doc2", "doc3"]
def test_empty_results_list(self):
"""Test filtering on empty results list."""