Skip to content

Relationships of a Runtime Type

A @GraphView declares its relationships, type included. When the type is data — a graph whose relationship types are not known when the model is written — use graphObjectManager.edges:

val lyre = nodeRef<ThingNode>("lyre")
val ada = nodeRef<PersonNode>("ada", "Author") // must also carry the label Author
graphObjectManager.edges.relate(lyre, ada, type = "OWNED_BY", properties = mapOf("since" to 1990))
graphObjectManager.edges.relate(lyre, ada, type = "PLAYED_BY", mode = RelateMode.CREATE)
val owners: List<PersonNode> = graphObjectManager.edges.loadRelated(lyre, "OWNED_BY", Direction.OUTGOING)
graphObjectManager.edges.unrelate(lyre, ada, "PLAYED_BY") // every PLAYED_BY from lyre to ada
graphObjectManager.edges.unrelateAll(lyre, "OWNED_BY") // every OWNED_BY that leaves lyre
  • A NodeRef names a stored node by fragment class and id. Both ends are matched, never created: if either is absent, or lacks a label the reference names, nothing is written and relate returns false. Neither node is loaded and neither’s properties are touched.
  • RelateMode.MERGE (the default) keeps at most one relationship of the type between the two nodes in that direction and sets its properties; CREATE makes another each time.
  • loadRelated returns each related node once, as the target fragment.
  • unrelate and unrelateAll remove relationships and return how many. No node is deleted.
  • relate, unrelate and unrelateAll give the nodes at both ends a new relationship token in their stamp when they change something, so a Replace from an object loaded before is refused. A relate that merges takes both nodes’ write locks before it looks for the relationship, so two of them on the same node run one after the other, or one is turned away by the engine and run again. A relate that finds the relationship there as it is, and an unrelate that finds none, mark neither.