fix: match list-valued metadata filters by item (#399)
This commit is contained in:
@@ -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:
|
||||
|
||||
@@ -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."""
|
||||
|
||||
Reference in New Issue
Block a user