Skip to content

Commit e99120d

Browse files
authored
feat: Add support for Sum and Avg aggregation query (#437)
1 parent 795ce81 commit e99120d

File tree

6 files changed

+663
-47
lines changed

6 files changed

+663
-47
lines changed

google/cloud/datastore/aggregation.py

Lines changed: 85 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -39,6 +39,9 @@ class BaseAggregation(ABC):
3939
Base class representing an Aggregation operation in Datastore
4040
"""
4141

42+
def __init__(self, alias=None):
43+
self.alias = alias
44+
4245
@abc.abstractmethod
4346
def _to_pb(self):
4447
"""
@@ -59,7 +62,7 @@ class CountAggregation(BaseAggregation):
5962
"""
6063

6164
def __init__(self, alias=None):
62-
self.alias = alias
65+
super(CountAggregation, self).__init__(alias=alias)
6366

6467
def _to_pb(self):
6568
"""
@@ -71,6 +74,60 @@ def _to_pb(self):
7174
return aggregation_pb
7275

7376

77+
class SumAggregation(BaseAggregation):
78+
"""
79+
Representation of a "Sum" aggregation query.
80+
81+
:type property_ref: str
82+
:param property_ref: The property_ref for the aggregation.
83+
84+
:type value: int
85+
:param value: The resulting value from the aggregation.
86+
87+
"""
88+
89+
def __init__(self, property_ref, alias=None):
90+
self.property_ref = property_ref
91+
super(SumAggregation, self).__init__(alias=alias)
92+
93+
def _to_pb(self):
94+
"""
95+
Convert this instance to the protobuf representation
96+
"""
97+
aggregation_pb = query_pb2.AggregationQuery.Aggregation()
98+
aggregation_pb.sum = query_pb2.AggregationQuery.Aggregation.Sum()
99+
aggregation_pb.sum.property.name = self.property_ref
100+
aggregation_pb.alias = self.alias
101+
return aggregation_pb
102+
103+
104+
class AvgAggregation(BaseAggregation):
105+
"""
106+
Representation of a "Avg" aggregation query.
107+
108+
:type property_ref: str
109+
:param property_ref: The property_ref for the aggregation.
110+
111+
:type value: int
112+
:param value: The resulting value from the aggregation.
113+
114+
"""
115+
116+
def __init__(self, property_ref, alias=None):
117+
self.property_ref = property_ref
118+
super(AvgAggregation, self).__init__(alias=alias)
119+
120+
def _to_pb(self):
121+
"""
122+
Convert this instance to the protobuf representation
123+
"""
124+
aggregation_pb = query_pb2.AggregationQuery.Aggregation()
125+
aggregation_pb.avg = query_pb2.AggregationQuery.Aggregation.Avg()
126+
aggregation_pb.avg.property.name = self.property_ref
127+
aggregation_pb.alias = self.alias
128+
return aggregation_pb
129+
130+
74131
class AggregationResult(object):
75132
"""
76133
A class representing result from Aggregation Query
@@ -154,6 +211,28 @@ def count(self, alias=None):
154211
self._aggregations.append(count_aggregation)
155212
return self
156213

214+
def sum(self, property_ref, alias=None):
215+
"""
216+
Adds a sum over the nested query
217+
218+
:type property_ref: str
219+
:param property_ref: The property_ref for the sum
220+
"""
221+
sum_aggregation = SumAggregation(property_ref=property_ref, alias=alias)
222+
self._aggregations.append(sum_aggregation)
223+
return self
224+
225+
def avg(self, property_ref, alias=None):
226+
"""
227+
Adds a avg over the nested query
228+
229+
:type property_ref: str
230+
:param property_ref: The property_ref for the sum
231+
"""
232+
avg_aggregation = AvgAggregation(property_ref=property_ref, alias=alias)
233+
self._aggregations.append(avg_aggregation)
234+
return self
235+
157236
def add_aggregation(self, aggregation):
158237
"""
159238
Adds an aggregation operation to the nested query
@@ -327,8 +406,7 @@ def _build_protobuf(self):
327406
"""
328407
pb = self._aggregation_query._to_pb()
329408
if self._limit is not None and self._limit > 0:
330-
for aggregation in pb.aggregations:
331-
aggregation.count.up_to = self._limit
409+
pb.nested_query.limit = self._limit
332410
return pb
333411

334412
def _process_query_results(self, response_pb):
@@ -438,5 +516,8 @@ def _item_to_aggregation_result(iterator, pb):
438516
:rtype: :class:`google.cloud.datastore.aggregation.AggregationResult`
439517
:returns: The list of AggregationResults
440518
"""
441-
results = [AggregationResult(alias=k, value=pb[k].integer_value) for k in pb.keys()]
519+
results = [
520+
AggregationResult(alias=k, value=pb[k].integer_value or pb[k].double_value)
521+
for k in pb.keys()
522+
]
442523
return results

tests/system/index.yaml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -39,9 +39,9 @@ indexes:
3939
- name: family
4040
- name: appearances
4141

42-
4342
- kind: Character
4443
ancestor: yes
4544
properties:
4645
- name: family
4746
- name: appearances
47+

0 commit comments

Comments
 (0)