Several aggregations in a Typescript Function

Hi,

I’m new to Typescript Functions (but not at all to Foundry). I try to do something very basic, but lack of documentation doesn’t help at all (or at least I didn’t find it…)
I have an objectSet filtered by user inputs. For the lines that exists in this filtered objectSet, I want to group by a date column, calculate the sum of 2 columns and divide these 2 sums. I just need the date and division in my result, that I will use to populate a chart in Workshop.

You would need to compute the individual aggregations separately, and then associate them bucket by bucket, with something like:

@Function()
public async getSomeMetricByDate(objects: ObjectSet<MyObjectType>): Promise<TwoDimensionalAggregation<IRange<Timestamp>, Double>> {
    const grouping = objects.groupBy(o => o.dateProperty.byDays());
    const [sum1, sum2] = await Promise.all([
        grouping.sum(o => o.property1),
        grouping.sum(o => o.property2)
    ]);
    const metric = this.zipTimestampBuckets((a, b) => (a + b)/2, sum1, sum2);
    return metric;
}

// This function ignores buckets that cannot be found in both aggregations
private zipTimestampBuckets(
    zipFunc: ((arg1:Double, arg2:Double) => Double),
    bucketsA: TwoDimensionalAggregation<IRange<Timestamp>>,
    bucketsB: TwoDimensionalAggregation<IRange<Timestamp>>
): TwoDimensionalAggregation<IRange<Timestamp>> {
    const zipped : TwoDimensionalAggregation<IRange<Timestamp>> = { buckets: [] };
    bucketsA.buckets.forEach(a => {
        const index = bucketsB.buckets.findIndex(b => {
            return this.areTimestampsEqual(b.key.min, a.key.min) && this.areTimestampsEqual(b.key.max, a.key.max)});
        if (index >= 0) {
            zipped.buckets.push({key: a.key, value: zipFunc(a.value, bucketsB.buckets[index].value)});
        }
    })
    return zipped;
}

private areTimestampsEqual(a: Timestamp | undefined, b: Timestamp | undefined): boolean {
    if (a == null || b == null) {
        return false;
    }
    return a.isEqual(b);
}
1 Like

Hi,

First: sorry for the end of my first message, I didn’t mean to send it but did on a bad click and then forgot to edit it, so it finishes quite hardly in my opinion.

Back on topic now: thanks for your answer @comew ! I struggled a bit but finally found how to do it, and it’s quite similar in the end. I just notice something, which will be more of an open question for my culture: I see you compare each bucket to correctly zip them with areTimestampsEqual. In my code I could see the sorting was the same for both sums as they base themselves on the same grouping. So I guess the sorting will always be the same, but I may be wrong seeing your code. Don’t know what you think of it

Hi @frello, glad you managed to implement the same! In practice, I believe that time-based buckets are usually ordered, but I’m not certain that there is actually such guarantee from the API, so it’s probably more robust and safer to not rely on this assumption. For instance, this part of the docs mentions ordering buckets in memory. And the two aggregations, although using the same grouping, are executed separately so also not sure that they would be ordered in the same way.

1 Like