Typescript backed filter on Pivot table for linked Objects

HI there @Palmaker. I think you got the gist of it in your code solution. There are a few issues to sort out and some potential improvements using Foundry’s own functions API instead of native TS. Take a look at this code:

import {ObjectSet,Objects,ObjectTypeA, ObjectTypeB} from "@foundry/ontology-api"
import {FunctionsMap, Double} from "@foundry/functions-api"


export class PivotTableFunctions {
    @Function()
    public static async getFilteredAggregations(projectIds: string[]): Promise<FunctionsMap<ObjectTypeA, Double>> {
        // Fetch all ObjectTypeA (row groupings remain unchanged)
        const aProjects = await Objects.search().objectTypeA().allAsync();

        // Fetch filtered ObjectTypeB entries directly using projectIds and aggregate booking value
        const filteredBookings = await Objects.search().objectTypeB()
            .filter(booking => booking.Project_id.exactMatch(...projectIds))
            .groupBy(booking => booking.Project_id.exactValues({maxBuckets: n}))
            .sum(booking => booking.value);
        
        // Map results
        const mapProjectValues = new Map <string, Double>()
        filteredBookings.buckets.forEach(bucket => {
            mapProjectValues.set(bucket.key.toString(), bucket.value || 0); 

        });

        // Create a FunctionsMap to store the results of ObjectTypeA data with aggregated values
        const resultMap = new FunctionsMap<ObjectTypeA, Double>();

        // Map results
        aProjects.forEach(project => {
            resultMap.set(project, mapProjectValues.get(project.Project_id) || 0)
        }); // Use `0` if no matching bookings
       return resultMap;
    }
}

Main changes:

  • The calls to Objects.search() was being done directly on ObjectsA.search(), ObjectsB.search() which, to my understanding, is not how it should be done. Rather, you call on Objects.search().yourObjectAPI() …
  • There are foundry-native ways to do the aggregations, so you don’t have to write custom logic from scratch by using the .groupBy clause after you call the search and filter (see here: https://alixpartners.palantirfoundry.com/docs/foundry/functions/api-object-sets#grouping-objects-by-properties and here: https://alixpartners.palantirfoundry.com/docs/foundry/notepad/widgets-functions#writing-batched-functions, for groupBy and FunctionsMap docs, respectively).
  • Changed the code to async in case there are a large number of projects for your use case, can be changed back if needed.
  • Removed the static declaration in the function definition as it wouldn’t let me test with that on, at least on the instance I’m working on.
  • You need to change the n {maxBuckets: n} to your desired number of max projects B tied to projects A (usual FoO apply).

Hope this helps!

2 Likes