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 adagraphObjectManager.edges.unrelateAll(lyre, "OWNED_BY") // every OWNED_BY that leaves lyre- A
NodeRefnames 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 andrelatereturns 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;CREATEmakes another each time.loadRelatedreturns each related node once, as the target fragment.unrelateandunrelateAllremove relationships and return how many. No node is deleted.relate,unrelateandunrelateAllgive the nodes at both ends a new relationship token in their stamp when they change something, so aReplacefrom an object loaded before is refused. Arelatethat 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. Arelatethat finds the relationship there as it is, and anunrelatethat finds none, mark neither.

