Aggregation

Sometimes you don’t need the actual data objects that are stored within the data grid, but the derived, calculated result based on them. This is where Coherence aggregation features come in handy.

Aggregations can be executed against the whole data set, or they can be limited to a subset of the data using a query or a key set. See the utility class Aggregators for the aggregators supported out-of-the-box by this client.

The following example demonstrates various aggregation operations against a NamedMap:

 1# Copyright (c) 2023, 2024, Oracle and/or its affiliates.
 2# Licensed under the Universal Permissive License v 1.0 as shown at
 3# https://oss.oracle.com/licenses/upl.
 4
 5import asyncio
 6from dataclasses import dataclass
 7from decimal import Decimal
 8from typing import Dict, List
 9
10from coherence import Aggregators, Filters, NamedMap, Session
11
12
13@dataclass
14class Hobbit:
15    """
16    A simple class representing a Hobbit.
17    """
18
19    id: int
20    name: str
21    age: int
22    hobbies: str
23
24
25async def do_run() -> None:
26    """
27    Demonstrates various Aggregator operations against a NamedMap.
28
29    :return: None
30    """
31    person_data = {
32        1: Hobbit(1, "Bilbo", 111, "Burglaring"),
33        2: Hobbit(2, "Frodo", 50, "Bearing"),
34        3: Hobbit(3, "Sam", 38, "Side Kick"),
35        4: Hobbit(3, "Meriadoc", 36, "Side Kick"),
36        5: Hobbit(3, "Peregrin", 28, "Side Kick"),
37    }
38
39    session: Session = await Session.create()
40    try:
41        named_map: NamedMap[int, Hobbit] = await session.get_map("aggregation-test")
42
43        await named_map.clear()
44
45        await named_map.put_all(person_data)
46
47        distinct_hobbies: List[str] = await named_map.aggregate(Aggregators.distinct("hobbies"))
48        print("Distinct hobbies :", distinct_hobbies)
49
50        count: int = await named_map.aggregate(Aggregators.count())
51        print("Number of Hobbits :", count)
52
53        over_forty: int = await named_map.aggregate(Aggregators.count(), filter=Filters.greater("age", 40))
54        print("Number of Hobbits older than 40 :", over_forty)
55
56        avg_under_forty: Decimal = await named_map.aggregate(Aggregators.average("age"), filter=Filters.less("age", 40))
57        print("Average age of Hobbits under 40 :", int(avg_under_forty))
58
59        print("The oldest Hobbit for each hobby ...")
60        results: Dict[str, int] = await named_map.aggregate(Aggregators.group_by("hobbies", Aggregators.max("age")))
61        for hobby, age in results.items():
62            print("Hobby: ", hobby, "Max age: ", age)
63    finally:
64        await session.close()
65
66
67asyncio.run(do_run())
  • Line 47 - Returns a list of distinct hobbies across all entries

  • Line 50 - Returns a count of all Hobbits

  • Line 53 - Returns a count of all Hobbits over age 40

  • Line 56 - Returns an average of all Hobbits under the age of 40

  • Line 60 - For each hobby, list the oldest Hobbit for that interest