Bulk Lookup by Name List
When you have a batch of names and need their IDs (e.g. a CSV column says "Backed by: Stability AI, Anthropic, OpenAI" and you need to convert those names to entity IDs to publish a relation), don't loop with N round-trips. Use a single bulk query.
Query
query BulkLookup($names: [String!]!) {
entities(
first: 100
filter: { name: { in: $names } }
) {
id
name
types { id name }
}
}
{ "names": ["OpenAI", "Anthropic", "Stability AI"] }
Response
{
"data": {
"entities": [
{ "id": "019d74a2f7ea4ffd9d3dfc07f25217df", "name": "OpenAI", "types": [{ "id": "e059a29e6f6b437bbc15c7983d078c0d", "name": "Company" }] },
{ "id": "09487a5ae4014091ba4310bd3d734bc5", "name": "OpenAI", "types": [{ "id": "e059a29e6f6b437bbc15c7983d078c0d", "name": "Company" }] },
{ "id": "150eb37e739346abb1021f3c291e54cc", "name": "Anthropic", "types": [{ "id": "e059a29e6f6b437bbc15c7983d078c0d", "name": "Company" }] }
]
}
}
Loading interactive query runner…
Building the lookup table client-side
const data = await gql(query, { names: ["OpenAI", "Anthropic", "Stability AI"] });
// One name can map to MULTIPLE entities — disambiguate by type and/or space
const byName = new Map<string, Array<{ id: string; types: string[] }>>();
for (const e of data.entities) {
const list = byName.get(e.name) ?? [];
list.push({ id: e.id, types: e.types.map((t) => t.id) });
byName.set(e.name, list);
}
// Resolve a name → ID, preferring entities of a specific type
function resolveName(name: string, expectedTypeId?: string): string | null {
const matches = byName.get(name);
if (!matches || matches.length === 0) return null;
if (expectedTypeId) {
const typed = matches.find((m) => m.types.includes(expectedTypeId));
if (typed) return typed.id;
}
return matches[0].id; // fallback: first match
}
Scoping bulk lookup to a space
query BulkLookupInSpace($names: [String!]!, $spaceId: UUID!) {
entities(
first: 100
filter: {
name: { in: $names }
spaceIds: { anyEqualTo: $spaceId }
}
) {
id
name
}
}
This is what you usually want during ingestion — "do any of these names already exist in my target space?".
Loading interactive query runner…
Notes
first: 100is the default cap — pass a largerfirstif you batch more than 100 names at once. The API doesn't enforce a hard limit but very large name lists may slow down the query.- Duplicate names are common: the API doesn't dedup names, so for popular names like
"OpenAI"you'll get multiple results. Always inspecttypesandspaceIdsto pick the right one. - Case-sensitive:
name: { in: [...] }is exact-match. For case-insensitive bulk lookup, you have to go one-by-one withname: { equalToInsensitive: ... }. Best to normalize your name list to the casing actually stored in the graph. - Versus a loop of single lookups: bulk is one HTTP round-trip vs N round-trips. For 50 names that's the difference between ~200ms and ~5s.