I’m working on creating a function-backed Search Around in Palantir Foundry, and I’m dealing with many-to-many links between objects. The challenge is that all links are stored in many-to-many tables, and the API names for the links follow this pattern:
relative_person_person_1 (source is _2, target is _1)
relative_person_person_2 (source is _1, target is _2)
associate_person_person_1
associate_person_person_2
My goal is to expand a person object to one degree by fetching all their relatives and associates, then return the relationships as directEdges in the IGraphSearchAroundResultV1 format.
This is a precursor to writing much more complex searcharound functions that will quickly enable analysts to expand the complex networks with a few clicks, rather than going through a very manual process of expanding one step and one link type at a time.
Am I missing something here? I have very complex data with numerous different object types and link types interconnecting all of it. I’m hoping there is a quicker way for our analysts to be able to expand the whole tree from a source object, either through a function or through some other functionality.
This seems like a great use of function-backed Search Arounds in Vertex.
If you wanted to explore both of those relations in both directions, I believe you could do something like the following, of course adapted to your exact ontology types:
import { Function } from "@foundry/functions-api";
import { IGraphSearchAroundResultV1, IGraphSearchAroundResultDirectEdgeV1 } from "@foundry/vertex-api";
const RELATIVE_LINK_TYPE_RID = "";
const ASSOCIATE_LINK_TYPE_RID = "";
export class SearchAroundFunctions {
@Function()
public async expandPersonNetwork(persons: Person[]): Promise<IGraphSearchAroundResultV1> {
const directEdges: IGraphSearchAroundResultDirectEdgeV1[] = [];
for (const person of persons) {
// Fetch relatives where person is the target
const [
relatives1,
relatives2,
associates1,
associates2
] = await Promise.all([
person.relative_person_person_1.allAsync(),
person.relative_person_person_2.allAsync(),
person.associate_person_person_1.allAsync(),
person.associate_person_person_2.allAsync(),
])
for (const relative of relatives1) {
directEdges.push({
sourceObjectRid: relative.rid,
targetObjectRid: person.rid,
linkTypeRid: RELATIVE_LINK_TYPE_RID,
});
}
for (const relative of relatives2) {
directEdges.push({
sourceObjectRid: person.rid,
targetObjectRid: relative.rid,
linkTypeRid: RELATIVE_LINK_TYPE_RID,
});
}
for (const associate of associates1) {
directEdges.push({
sourceObjectRid: associate.rid,
targetObjectRid: person.rid,
linkTypeRid: ASSOCIATE_LINK_TYPE_RID,
});
}
for (const associate of associates2) {
directEdges.push({
sourceObjectRid: person.rid,
targetObjectRid: associate.rid,
linkTypeRid: ASSOCIATE_LINK_TYPE_RID,
});
}
}
return { directEdges };
}
}