How to define function backed searcharounds with many-to-many links

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 };
    }
}