Skip to main content

Adding Custom Relationships

Feature Availability
DataHub Core (OSS)
DataHub Cloud
Private BetaInvite-only and evolving rapidly. Contact your DataHub Cloud representative to request access.

The built-in vocabulary — Inherits, Contains, Synonym, Antonym, Translates to, Valid value, Related to — covers general-purpose glossary modelling, but not vocabulary specific to your organization. For relationships like governed by, derived from, certified by, or supersedes, you can define your own relationship types.

You do this with a relationship Structured Property.

Available in DataHub Cloud v2.2.1 and later.

How it works

A Structured Property whose value type is a DataHub entity already points from one asset to another. Flipping the relationship switch on that property tells DataHub to also materialize each assignment as a real edge in the metadata graph — so the property starts behaving like a first-class relationship: it is drawn in the ontology graph, it is walkable by the traverse APIs, and it is reachable from SPARQL.

Two entities are involved, and it is worth knowing which does what:

  • The structured property is the veneer. It is what users assign, and what shows up in the property UI.
  • The relationship type (urn:li:relationshipType:*) carries the predicate identity: the display name, direction semantics, transitivity, reverse label, and RDF predicate mapping. Graph edges are keyed by this, not by the property.

You do not normally create the relationship type by hand — the UI and the GraphQL create/update paths create it and wire up the pointer for you.

Creating a relationship property in the UI

  1. Go to Govern → Structured Properties and create a new property.
  2. Set the value type to a DataHub entity type, and restrict the allowed types to what the relationship should point at — for a term-to-term relationship, Glossary Term on both sides.
  3. Open Display Preferences and turn on Treat as Relationship.
  4. Configure the relationship's semantics (see below).
  5. Save.

The Treat as Relationship toggle and its semantics settings

The Treat as Relationship switch is only available on entity-valued properties — there is nothing to point at otherwise. Switching a property's value type away from an entity type clears the relationship setting.

Relationship semantics

Once the switch is on, four settings define what the relationship means:

SettingWhat it does
DirectionDirected (default) runs source → destination. Undirected is symmetric — the walk traverses it both ways regardless of the direction requested.
Reverse LabelThe label for reading a directed relationship backwards ("Governs" for a forward "Governed By"). Display only; it never creates a second edge.
TransitiveDeclares that chaining over this relationship is meaningful — A → B → C implies A → C. Surfaced to traversal clients and used by SPARQL's RDFS regime.
Equivalent PropertiesStandard-vocabulary predicates this relationship corresponds to, as CURIEs or IRIs (skos:broader, skos:exactMatch). Lets standards-based queries reach your edges.

Set these carefully. Direction and transitivity affect how the relationship is traversed, so they change the results anything walking the graph gets back.

Creating a relationship property via the API

mutation {
createStructuredProperty(
input: {
id: "governedBy"
qualifiedName: "governedBy"
displayName: "Governed By"
description: "The regulation or policy term that governs this concept."
valueType: "urn:li:dataType:datahub.urn"
cardinality: MULTIPLE
entityTypes: ["urn:li:entityType:datahub.glossaryTerm"]
typeQualifier: {
allowedTypes: ["urn:li:entityType:datahub.glossaryTerm"]
}
settings: {
isRelationship: true
relationshipSemantics: {
directionMode: DIRECTED
reverseDisplayName: "Governs"
transitive: false
equivalentProperties: ["skos:broader"]
}
}
}
) {
urn
}
}

This creates both the structured property and the relationship type it points at (urn:li:relationshipType:governedBy, sharing the property's id).

Assigning the relationship

Once defined, the property is assigned like any other structured property — the values are the URNs of the entities on the far end:

mutation {
upsertStructuredProperties(
input: {
assetUrn: "urn:li:glossaryTerm:customer"
structuredPropertyInputParams: [
{
structuredPropertyUrn: "urn:li:structuredProperty:governedBy"
values: [{ stringValue: "urn:li:glossaryTerm:gdpr" }]
}
]
}
) {
properties {
structuredProperty {
urn
}
}
}
}

On a glossary term, custom relationships also appear in the Related Terms tab alongside the built-in ones, and can be added and removed there.

Edges are materialized asynchronously, so a newly assigned relationship takes a moment to appear in the graph and the traverse APIs.

Querying custom relationships

Custom relationship types are traversed exactly like built-in ones — pass the relationship type URN where you would pass a built-in name:

curl -H "Authorization: Bearer $DATAHUB_TOKEN" \
"$DATAHUB_GMS_URL/openapi/v3/relationship/traverse\
?urn=urn:li:glossaryTerm:customer\
&relationshipTypes=urn:li:relationshipType:governedBy\
&direction=OUTGOING"

The structured property URN (urn:li:structuredProperty:governedBy) is accepted too and resolves to the same relationship type. See Querying Your Ontology.

Modelling guidance

  • One relationship per meaning. Resist reusing Related to with a comment explaining what was actually meant. A distinct type is what makes the edge queryable and reasonable-over.
  • Name both directions. A reverse display name costs nothing and makes every reverse-direction view of your graph readable.
  • Only mark transitive when it is true. Transitivity licenses inference; a wrong claim produces confidently wrong answers under closure.
  • Map to standards where one fits. Declaring skos:broader or rdfs:subClassOf as an equivalent property means external tooling and standards-based queries can reach your relationship without knowing DataHub's naming.
  • Deleting the property removes the edges. Removing a relationship structured property reaps the graph edges it materialized.

Enabling this feature

Contact your DataHub representative to have this enabled for your instance.

Without the flag, DataHub rejects attempts to define a new relationship property rather than letting you declare a relationship that would silently never materialize any edges.

For self-managed deployments, set the flag and restart:

STRUCTURED_PROPERTY_GRAPH_EDGES_ENABLED=true

The flag has to match across GMS and, if you run standalone consumers, the MAE and MCE consumers: the MAE consumer materializes the edges and the MCE consumer gates defining relationship properties. Via Helm, the single global value covers all three:

global:
datahub:
structuredPropertyGraphEdgesEnabled: true