@@ -632,24 +632,53 @@ async def count_unique_metadata_by_filter_async(
632632
633633 return result
634634
635+ @staticmethod
636+ def _compute_field_unique_values (
637+ agg_result : Any , search_term : str | None , from_ : int , size : int
638+ ) -> tuple [list [str ], int ]:
639+ """
640+ Computes paginated unique values from a Weaviate group-by aggregation result.
641+
642+ Weaviate's `like` filter only supports case-sensitive substring matching, so instead of
643+ filtering server-side (which would be case-sensitive), all groups are fetched unconditionally
644+ and `search_term` is applied here as a case-insensitive substring match in Python.
645+
646+ :param agg_result: The group-by aggregation result, with one group per unique field value.
647+ :param search_term: Optional term to filter the values by, matched as a case-insensitive
648+ substring against each value.
649+ :param from_: The starting offset for pagination (0-indexed).
650+ :param size: The maximum number of unique values to return.
651+ :returns: A tuple of (paginated list of unique values, total count of unique values).
652+ """
653+ all_values = [str (g .grouped_by .value ) for g in agg_result .groups ] if agg_result .groups else []
654+ if search_term :
655+ search_term_lower = search_term .lower ()
656+ all_values = [value for value in all_values if search_term_lower in value .lower ()]
657+ all_values .sort () # Sort for consistent pagination
658+ total_count = len (all_values )
659+
660+ paginated_values = all_values [from_ : from_ + size ]
661+
662+ return paginated_values , total_count
663+
635664 def get_metadata_field_unique_values (
636665 self ,
637666 metadata_field : str ,
638667 search_term : str | None = None ,
639668 from_ : int = 0 ,
640- size : int = 10000 ,
669+ size : int = 10 ,
641670 ) -> tuple [list [str ], int ]:
642671 """
643672 Returns unique values for a metadata field with pagination support.
644673
645674 :param metadata_field: The metadata field name to get unique values for.
646675 Can be prefixed with 'meta.' (e.g., 'meta.category' or 'category').
647- :param search_term: Optional term to filter documents by content before
648- extracting unique values . If provided, only documents whose content
649- contains this term will be considered.
650- Note: Uses substring matching (case-sensitive, no stemming).
676+ :param search_term: Optional term to filter the metadata field's values by
677+ before returning them . If provided, only values of `metadata_field` that
678+ contain this term will be considered.
679+ Note: Uses case-insensitive substring matching (no stemming).
651680 :param from_: The starting offset for pagination (0-indexed). Defaults to 0.
652- :param size: The maximum number of unique values to return. Defaults to 10000 .
681+ :param size: The maximum number of unique values to return. Defaults to 10 .
653682 :returns: A tuple of (list of unique values, total count of unique values).
654683 :raises ValueError: If the field is not found in the collection schema.
655684 """
@@ -661,45 +690,33 @@ def get_metadata_field_unique_values(
661690 msg = f"Field '{ field_name } ' not found in collection schema"
662691 raise ValueError (msg )
663692
664- weaviate_filter = None
665- if search_term :
666- weaviate_filter = convert_filters ({"field" : "content" , "operator" : "contains" , "value" : search_term })
667-
668693 # Weaviate's GroupByAggregate has a default limit of 100 groups.
669694 # We use the document count as the limit to ensure all unique values are retrieved,
670695 # since the number of unique values cannot exceed the number of documents.
671696 doc_count = self .collection .aggregate .over_all (total_count = True ).total_count or 0
672697
673- agg_result = self .collection .aggregate .over_all (
674- filters = weaviate_filter , group_by = GroupByAggregate (prop = field_name , limit = doc_count )
675- )
698+ agg_result = self .collection .aggregate .over_all (group_by = GroupByAggregate (prop = field_name , limit = doc_count ))
676699
677- all_values = [str (g .grouped_by .value ) for g in agg_result .groups ] if agg_result .groups else []
678- all_values .sort () # Sort for consistent pagination
679- total_count = len (all_values )
680-
681- paginated_values = all_values [from_ : from_ + size ]
682-
683- return paginated_values , total_count
700+ return self ._compute_field_unique_values (agg_result , search_term , from_ , size )
684701
685702 async def get_metadata_field_unique_values_async (
686703 self ,
687704 metadata_field : str ,
688705 search_term : str | None = None ,
689706 from_ : int = 0 ,
690- size : int = 10000 ,
707+ size : int = 10 ,
691708 ) -> tuple [list [str ], int ]:
692709 """
693710 Asynchronously returns unique values for a metadata field with pagination support.
694711
695712 :param metadata_field: The metadata field name to get unique values for.
696713 Can be prefixed with 'meta.' (e.g., 'meta.category' or 'category').
697- :param search_term: Optional term to filter documents by content before
698- extracting unique values . If provided, only documents whose content
699- contains this term will be considered.
700- Note: Uses substring matching (case-sensitive, no stemming).
714+ :param search_term: Optional term to filter the metadata field's values by
715+ before returning them . If provided, only values of `metadata_field` that
716+ contain this term will be considered.
717+ Note: Uses case-insensitive substring matching (no stemming).
701718 :param from_: The starting offset for pagination (0-indexed). Defaults to 0.
702- :param size: The maximum number of unique values to return. Defaults to 10000 .
719+ :param size: The maximum number of unique values to return. Defaults to 10 .
703720 :returns: A tuple of (list of unique values, total count of unique values).
704721 :raises ValueError: If the field is not found in the collection schema.
705722 """
@@ -712,27 +729,15 @@ async def get_metadata_field_unique_values_async(
712729 msg = f"Field '{ field_name } ' not found in collection schema"
713730 raise ValueError (msg )
714731
715- weaviate_filter = None
716- if search_term :
717- weaviate_filter = convert_filters ({"field" : "content" , "operator" : "contains" , "value" : search_term })
718-
719732 # Weaviate's GroupByAggregate has a default limit of 100 groups.
720733 # We use the document count as the limit to ensure all unique values are retrieved,
721734 # since the number of unique values cannot exceed the number of documents.
722735 doc_count_result = await collection .aggregate .over_all (total_count = True )
723736 doc_count = doc_count_result .total_count or 0
724737
725- agg_result = await collection .aggregate .over_all (
726- filters = weaviate_filter , group_by = GroupByAggregate (prop = field_name , limit = doc_count )
727- )
738+ agg_result = await collection .aggregate .over_all (group_by = GroupByAggregate (prop = field_name , limit = doc_count ))
728739
729- all_values = [str (g .grouped_by .value ) for g in agg_result .groups ] if agg_result .groups else []
730- all_values .sort () # Sort for consistent pagination
731- total_count = len (all_values )
732-
733- paginated_values = all_values [from_ : from_ + size ]
734-
735- return paginated_values , total_count
740+ return self ._compute_field_unique_values (agg_result , search_term , from_ , size )
736741
737742 @staticmethod
738743 def _to_data_object (document : Document ) -> dict [str , Any ]:
0 commit comments