From b0a85543e80e5d405cf96e650963613880cdb3a6 Mon Sep 17 00:00:00 2001 From: "David S. Batista" Date: Thu, 6 Aug 2026 13:13:56 +0200 Subject: [PATCH] adding filter to unique metadata values --- .../document_stores/ibm_db/document_store.py | 13 +++++++++++-- integrations/ibm_db/tests/test_document_store.py | 13 +++++++++++++ 2 files changed, 24 insertions(+), 2 deletions(-) diff --git a/integrations/ibm_db/src/haystack_integrations/document_stores/ibm_db/document_store.py b/integrations/ibm_db/src/haystack_integrations/document_stores/ibm_db/document_store.py index aeae379dbb..0847a12d21 100644 --- a/integrations/ibm_db/src/haystack_integrations/document_stores/ibm_db/document_store.py +++ b/integrations/ibm_db/src/haystack_integrations/document_stores/ibm_db/document_store.py @@ -609,6 +609,7 @@ def get_metadata_field_unique_values( search_term: str | None = None, from_: int = 0, size: int = 10, + filters: dict[str, Any] | None = None, ) -> tuple[list[Any], int]: """ Get unique values for a given metadata field, optionally filtered by a search term. @@ -619,6 +620,7 @@ def get_metadata_field_unique_values( are considered. :param from_: The offset for pagination (0-based). :param size: The number of unique values to return. + :param filters: Optional filters to restrict the documents considered. :return: A tuple containing (list of unique values in their original JSON type, total count of unique values matching `search_term`). """ @@ -628,12 +630,19 @@ def get_metadata_field_unique_values( # applied directly to a JSON_VALUE(...) expression derived from the BLOB `meta` column. Wrapping # the extraction in a derived table materializes it as a plain VARCHAR column first, so DISTINCT # and ORDER BY in the outer query operate on that column instead of the LOB-derived expression. + # `filters` is applied inside this subquery (not the outer one) since it references the raw + # `meta` column, which only exists at this level — the outer query only sees the extracted `value`. + params: list[Any] = [] + filter_where = "" + if filters: + filter_expression = FilterTranslator().translate(filters, params) + filter_where = f" WHERE {filter_expression}" + value_subquery = ( f"SELECT JSON_VALUE(SYSTOOLS.BSON2JSON(meta), '$.{field_name}' RETURNING VARCHAR(1000)) AS value " - f"FROM {self.table_name}" + f"FROM {self.table_name}{filter_where}" ) - params: list[Any] = [] search_clause = "" if search_term is not None: search_clause = " AND LOCATE(UPPER(?), UPPER(value)) > 0" diff --git a/integrations/ibm_db/tests/test_document_store.py b/integrations/ibm_db/tests/test_document_store.py index a8b6c8ee36..42f1afa297 100644 --- a/integrations/ibm_db/tests/test_document_store.py +++ b/integrations/ibm_db/tests/test_document_store.py @@ -309,6 +309,19 @@ def test_get_metadata_field_unique_values_preserves_non_string_types(self, docum assert set(values) == {1, 2} assert total == 2 + def test_get_metadata_field_unique_values_with_filters(self, document_store: IBMDb2DocumentStore): + docs = [ + Document(content="Doc 1", meta={"category": "A", "status": "active"}), + Document(content="Doc 2", meta={"category": "B", "status": "active"}), + Document(content="Doc 3", meta={"category": "C", "status": "inactive"}), + ] + document_store.write_documents(docs) + + filters = {"field": "meta.status", "operator": "==", "value": "active"} + values, total = document_store.get_metadata_field_unique_values("category", filters=filters) + assert set(values) == {"A", "B"} + assert total == 2 + def test_get_metadata_field_unique_values_invalid_field_name(self, document_store: IBMDb2DocumentStore): with pytest.raises(ValueError, match="Invalid metadata field name"): document_store.get_metadata_field_unique_values("field' OR '1'='1")