본문으로 건너뛰기
Ontology Modeler Path

Relationships — connect two entities and set the cardinality

From the builder canvas, drag from a source entity to a target entity to create a relation, then close the loop on naming convention (verb_phrase), cardinality (1:1, 1:N, N:N), and backing-dataset mapping. The example walks through the three relations of the retail supply-chain scenario.

10

Defining two entities does not yet make a graph. It's only at the moment you state how the two entities are connected in meaning that you have a graph. This lesson creates that meaning — a relation — on the builder canvas in one go. The example is the retail supply-chain scenario's 4-entity, 3-relation structure (RI_Product, RI_Branch, RI_Region, RI_Supplier + RI_STOCKED_AT, RI_LOCATED_IN, RI_SUPPLIED_BY).

Prerequisites

  • From the previous two lessons, your collection has at least two entities defined, each with its backing-dataset mapping done.
  • Or, for a fast entry, import the retail_inventory_intelligence scenario from dhub2-examples so the four entities are already on the canvas.

Start with two entity nodes visible on the builder canvas.

Create a relation by dragging on the canvas

  1. Hover the edge of the source entity node (RI_Product) and a small connection handle (a dot) appears.
  2. Click the handle and drag straight to the target entity node (RI_Branch).
  3. Release, and the Create Relationship dialog opens.

This dialog gathers the input for the next five areas in one place.

1. Source / Target — direction

  • Source Entity — Where the relation starts (the subject).
  • Target Entity — Where the relation ends (the object).

Direction follows the grammatical subject / object. Retail examples:

  • RI_Product -[RI_STOCKED_AT]-> RI_BranchThe product is stocked at a branch.
  • RI_Branch -[RI_LOCATED_IN]-> RI_RegionThe branch is located in a region.
  • RI_Product -[RI_SUPPLIED_BY]-> RI_SupplierThe product is supplied by a supplier.

Reversing the direction makes Cypher queries awkward (you'd have to flip to RI_Branch -[CONTAINS]-> RI_Product and re-explain). The chosen direction is immediately visible in the next lesson's Graph explorer, so decide carefully up front.

2. Type — the name that goes straight into Cypher

  • Type — The relation's system name. Uppercase + UPPER_SNAKE_CASE + verb_phrase is the standard. Exposed verbatim as :TYPE in Cypher queries.
  • Good examples: STOCKED_AT, LOCATED_IN, SUPPLIED_BY, PURCHASED, MANAGES.
  • Examples to avoid: Stocked_at (mixed case), stock (noun form — looks like a state, not an action), RELATES_TO (meaningless).

A domain prefix is often recommended (RI_STOCKED_AT, IOT_reads_from). It reduces slug collisions even within one collection and visually separates which domain a relation belongs to in global search.

3. Alias / Description — natural-language labels

  • Alias — The primary label users see. Natural English (Stocked at, Located in, Supplied by).
  • Description — A one-line natural-language description. The AI auto-generate button is there, but words from your own domain will save your future self in 6 months.

The UI primary title is the alias; the subtitle is the system type.

4. Schema — Identity Keys / Display Column

Relations can have the same schema metadata as entities.

  • Identity Keys — The key columns that uniquely identify a relation instance. Required for Relation I/O in a pipeline.
  • Display Column — The label of a relation instance.

A relation's schema is the relation's own attributes. In the retail example, RI_STOCKED_AT is not just a connecting line — it carries attributes like:

  • inventory_qty (current inventory amount)
  • inventory_turnover_rate (turnover rate)
  • selling_price_krw_synth, safety_stock_level, stockout_risk_flag_synth
  • Many more around price, discount, and promotion

By contrast, RI_LOCATED_IN and RI_SUPPLIED_BY have empty schema fields — for both, the connection itself is the whole meaning. Both are valid.

5. Backing dataset — relations can be mapped too

If a relation has schema fields, those rows must come from somewhere — wire it to a backing dataset. The flow is identical to entity mapping.

  1. The relation inspector's Data Source tab.
  2. Select a dataset in the same collection (e.g. RI_STOCKED_ATstock_levels dataset).
  3. Map relation attributes to dataset columns 1:1.
  4. Specify the Identity Keys mapping — row-level query becomes possible.

Once mapping completes, this relation is automatically registered in the mapped dataset's References tab. The sink runs automatically at mapping time (no separate UI, same as the previous lesson).

Cardinality — 1:1 · 1:N · N:N

In the relation inspector's Constraints area, declare the cardinality.

CardinalityMeaningRetail example
1:1A source instance connects to exactly one targetRare in practice
1:NA source connects to many targets; a target connects to only one sourceRI_LOCATED_IN — A branch sits in only one region, a region holds many branches
N:NBoth sides can connect to many instancesRI_STOCKED_AT — One product across many branches, one branch holds many products. RI_SUPPLIED_BY — One product can come from many suppliers, one supplier covers many products

Cardinality is a validation signal. Setting it wrong makes the builder's validation panel raise a warning, or makes Cypher results show patterns you didn't intend.

Self-reference — a relation within one entity

An entity can have a relation to itself. Common examples:

  • Person -[MANAGES]-> Person — An employee manages another employee.
  • RI_Product -[SUBSTITUTES]-> RI_Product — A product substitutes for another product.

Self-reference relations are visualized as loop edges in the Graph explorer. They appear often when dealing with tree or hierarchy structures.

Quick check — 4 entities and 3 relations

The retail example's end state, viewed on the canvas, looks like this:

       RI_Region
          ▲ RI_LOCATED_IN (1:N)
          │
       RI_Branch
          ▲ RI_STOCKED_AT (N:N)  
          │
       RI_Product ──RI_SUPPLIED_BY (N:N)──▶ RI_Supplier

By the end of this lesson, the same shape should be visible on your own collection.

Self-check

  • At least one arrow (edge) is visible between two entities on the canvas.
  • The relation type is UPPER_SNAKE_CASE + verb_phrase.
  • The alias is filled with natural language, so node labels don't feel awkward.
  • If the relation has schema fields, the backing-dataset mapping is done.
  • A single cardinality is decided.

Next lesson

The next lesson confirms how the 4 entities and 3 relations defined so far appear as instances in the Graph explorer. We'll cover label clicks, double-click neighbor expansion, and the three-line Cypher pattern (MATCH · RETURN · LIMIT).