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!