Querying Your Ontology
Ontology is currently in Private Beta. Features, UI, and configuration options are subject to change.
This page covers reading the relationship graph from code, and from an AI agent.
All the surfaces here run the same multi-hop relationship walk: start at an entity, follow a named set of relationship types, up to a maximum number of hops, and return everything reached.
Available in DataHub Cloud v2.2.1 and later; no feature flag is required.
Discovering what you can traverse
There is no "all relationship types" wildcard — you name the types you want to walk. To find out
which types exist on your instance, export the relationship-graph schema. It returns every
relationship type with the entity types it connects, its direction semantics, and whether it is
built in (NATIVE) or user-defined (CUSTOM):
curl -H "Authorization: Bearer $DATAHUB_TOKEN" \
"$DATAHUB_GMS_URL/openapi/v3/relationship/schema?entityType=glossaryTerm"
PREFIX dh: <urn:li:ontology:>
PREFIX et: <urn:li:entityType:datahub.>
PREFIX rel: <urn:li:relationshipType:>
PREFIX schema: <https://schema.org/>
rel:governedBy rdf:type rdf:Property ;
rdfs:label "Governed By" ;
rdfs:comment "The regulation or policy term that governs this concept." ;
schema:domainIncludes et:glossaryTerm ;
schema:rangeIncludes et:glossaryTerm ;
dh:origin "CUSTOM" ;
dh:reverseDisplayName "Governs" .
The subjects it returns are exactly the values you pass as relationship types below. Add
?format=json-ld (or n-triples, rdf-xml) if Turtle is not what you want.
Traversing from the REST API
GET /openapi/v3/relationship/traverse walks the graph and returns the entities it reached:
curl -H "Authorization: Bearer $DATAHUB_TOKEN" \
"$DATAHUB_GMS_URL/openapi/v3/relationship/traverse\
?urn=urn:li:glossaryTerm:customer\
&relationshipTypes=IsA\
&relationshipTypes=urn:li:relationshipType:governedBy\
&direction=UNDIRECTED\
&maxHops=2"
{
"count": 2,
"total": 2,
"partial": false,
"relationships": [
{
"relationshipType": "urn:li:relationshipType:governedBy",
"entityType": "glossaryTerm",
"urn": "urn:li:glossaryTerm:gdpr",
"degree": 1,
"degrees": [1],
"directionMode": "DIRECTED",
"transitive": false,
"reverseDisplayName": "Governs"
},
{
"relationshipType": "IsA",
"entityType": "glossaryTerm",
"urn": "urn:li:glossaryTerm:businessCustomer",
"degree": 1,
"degrees": [1],
"directionMode": "DIRECTED",
"transitive": false
}
]
}
Parameters
| Parameter | Meaning |
|---|---|
urn | The entity to start from. Required. |
relationshipTypes | Repeatable. Built-in names (IsA, HasA, DownstreamOf, …) and/or urn:li:relationshipType:* URNs, traversed uniformly. A urn:li:structuredProperty:* URN is accepted too and resolves to the relationship type it points at. Required unless includeLineage=true. |
direction | OUTGOING (default), INCOMING, or UNDIRECTED. Edges point from the entity holding the metadata to the entity it references, so INCOMING from X returns entities whose edges point at X. Symmetric relationship types are walked both ways regardless. |
maxHops | Traversal depth, 1–20. Defaults to 1. |
entityTypes | Repeatable. Constrains the entity types visited at every hop, not just the final results. |
includeLineage | Also walk the full native lineage edge set in the same call, without enumerating lineage relationship types. |
lineageDirection | UPSTREAM, DOWNSTREAM, or BOTH (default). Only meaningful with includeLineage=true. |
resolveEquivalents | Expand a requested standard-vocabulary predicate (e.g. skos:broader) to the relationship types that declare it as an equivalent. |
degree is the hop distance from the start entity; degrees lists every depth at which the entity
was reached. partial: true means the walk hit a traversal limit or timed out — narrow the query.
Traversing from GraphQL
The searchAcrossRelationships query is the same walk with hydrated entities, plus paging. This is
what the ontology graph UI itself calls:
query {
searchAcrossRelationships(
input: {
urn: "urn:li:glossaryTerm:customer"
relationshipTypes: ["IsA", "HasA", "urn:li:relationshipType:governedBy"]
direction: UNDIRECTED
maxHops: 2
count: 50
}
) {
total
isPartial
relationships {
relationshipType
degree
directionMode
transitive
reverseDisplayName
entity {
urn
... on GlossaryTerm {
properties {
name
description
}
}
}
}
}
}
Page with start and count. isPartial carries the same meaning as partial above.
relationshipTypes and direction apply only to the named-relationship walk. When
includeLineage is true, the full native lineage edge set is traversed as well — controlled solely
by lineageDirection — and the two walks are unioned. For pure data-flow questions ("what feeds
this table?"), use the lineage APIs instead; they are built for it.
Querying from an AI agent
DataHub's MCP server exposes the same walk as the get_relationships tool, so an assistant can
answer ontology questions directly. Paired with get_metadata_graph — the MCP equivalent of the
schema export above — an agent can discover what relationship types exist and then traverse them,
without any of them being hardcoded.
A useful pattern to give an agent:
Call
get_metadata_graphfirst to see which relationship types connect which entity types on this instance, then callget_relationshipswith the ones relevant to the question.
get_relationships mirrors the REST parameters (urn, relationship_types, direction,
max_hops, entity_types, include_lineage, lineage_direction), and adds a fields allowlist
so the agent only pulls the entity fields it needs — keeping more results inside its token budget.
Results are paged: pass the response's nextOffset back as offset and stop when hasMore is
false.
See DataHub MCP Server for connecting an agent to your instance.
Practical notes
- Name your types. There is no wildcard. A walk over the wrong types returns nothing, and it looks identical to a walk over an entity with no relationships.
- Be careful with
entityTypeson multi-hop walks. The filter applies at every hop, so a path that passes through an excluded entity type is cut short. Prefer omitting it whenmaxHops > 1. - Watch for
isPartial/partial. A capped walk is not an empty one. Narrow the relationship types or entity types, or reduce the hop count, rather than trusting a truncated answer. - Authorization applies. A walk only returns entities the caller is allowed to view.
If you need to express the query itself in a standard graph query language rather than as walk parameters, see Advanced Querying with SPARQL.