From 98d2b5a0b2bfb206cdb2ed68c5d8c91d4975a7f7 Mon Sep 17 00:00:00 2001 From: ktz03 <2484593937@qq.com> Date: Fri, 9 Oct 2026 15:08:47 +0800 Subject: [PATCH] fix(aggregate): request top occurrence values over gRPC --- test/collection/test_aggregate_metrics.py | 66 +++++++++++++++++++++++ weaviate/collections/classes/aggregate.py | 2 +- 2 files changed, 67 insertions(+), 1 deletion(-) create mode 100644 test/collection/test_aggregate_metrics.py diff --git a/test/collection/test_aggregate_metrics.py b/test/collection/test_aggregate_metrics.py new file mode 100644 index 000000000..dd4e2bece --- /dev/null +++ b/test/collection/test_aggregate_metrics.py @@ -0,0 +1,66 @@ +from typing import Optional +from unittest.mock import patch + +import pytest + +from weaviate import WeaviateClient +from weaviate.classes.aggregate import Metrics +from weaviate.connect import ConnectionParams +from weaviate.proto.v1 import aggregate_pb2 +from weaviate.util import _ServerVersion + + +@pytest.mark.parametrize("limit", [None, 3]) +@pytest.mark.parametrize( + "count,top_occurrences_count,top_occurrences_value,expected_top_occurrences", + [ + (False, False, False, True), # All-false arguments select all text metrics. + (False, False, True, True), + (False, True, False, True), + (False, True, True, True), + (True, False, False, False), + (True, False, True, True), + (True, True, False, True), + (True, True, True, True), + ], +) +def test_text_top_occurrences_grpc_request( + count: bool, + top_occurrences_count: bool, + top_occurrences_value: bool, + expected_top_occurrences: bool, + limit: Optional[int], +) -> None: + client = WeaviateClient( + connection_params=ConnectionParams.from_url("http://localhost:8080", 50051), + skip_init_checks=True, + ) + client._connection._weaviate_version = _ServerVersion.from_string("1.29.0") + metric = Metrics("title").text( + count=count, + top_occurrences_count=top_occurrences_count, + top_occurrences_value=top_occurrences_value, + limit=limit, + ) + try: + with patch.object( + client._connection, + "grpc_aggregate", + return_value=aggregate_pb2.AggregateReply(), + ) as send: + client.collections.use("Article").aggregate.over_all(return_metrics=metric) + + request = aggregate_pb2.AggregateRequest.FromString( + send.call_args.kwargs["request"].SerializeToString() + ) + assert request.collection == "Article" + assert len(request.aggregations) == 1 + aggregation = request.aggregations[0] + assert aggregation.property == "title" + assert aggregation.text.count == metric.count + assert aggregation.text.top_occurences == expected_top_occurrences + assert aggregation.text.HasField("top_occurences_limit") == (limit is not None) + if limit is not None: + assert aggregation.text.top_occurences_limit == limit + finally: + client.close() diff --git a/weaviate/collections/classes/aggregate.py b/weaviate/collections/classes/aggregate.py index a1e7596c3..238fb2802 100644 --- a/weaviate/collections/classes/aggregate.py +++ b/weaviate/collections/classes/aggregate.py @@ -175,7 +175,7 @@ def to_grpc(self) -> aggregate_pb2.AggregateRequest.Aggregation: property=self.property_name, text=aggregate_pb2.AggregateRequest.Aggregation.Text( count=self.count, - top_occurences=self.top_occurrences_count, + top_occurences=self.top_occurrences_count or self.top_occurrences_value, top_occurences_limit=self.limit, ), )