10 Choosing between relation, reference and embedded
This is the modelling choice you make most often.
| Embedded | Reference | Relation | |
|---|---|---|---|
| Identity | none: owned by the parent | the target is a node | both ends are nodes |
| Direction | n/a | one way | both ways, automatic |
| Reverse lookup | n/a | no | yes, indexed |
Traversable (Traverse, ShortestPath) |
no | no | yes |
| Filter by target | no | yes, with Indexed = true |
yes, WhereRelates |
| Order kept | yes | References<T>: yes |
yes, per end, and reorderable (§9.1) |
| Duplicates | yes | References<T>: yes |
no: relating an existing pair throws |
| Cost of a change | rewrites the parent | rewrites the parent | an index update, no node rewrite |
| Lifetime | dies with the parent | independent | independent |
Decision guide
- The data means nothing outside its parent, and you never query it on its own: embedded.
- You need the same target more than once, and never the reverse lookup:
References<T>. Order alone is no reason to choose it: relation lists are ordered too, and can be reordered. - You point at one thing, cheaply, and never ask "what points at me?":
Reference<T>. - You need reverse navigation, traversal, relation filters or facets, or a hand-curated order: relation. When in doubt, choose a relation.
In the running example:
IVenue.Hoursis embedded: opening hours mean nothing without their venue.IEvent.Coveris aReference<IMediaAsset>: nobody asks an image which events use it.IEvent.Sponsorsis aReferences<IOrganizer>: one organizer can appear twice, at different billing tiers. The duplicates rule out a relation.- Event ↔ venue and event ↔ attendee are relations: both directions are read all the time, and a venue's events are ordered by hand.
- How an editor shows them: Display — Display says how an editing interface, such as the Relatude CMS, shows the nodes a property holds. It goes on [RelationProperty], [ReferenceProperty], [ReferencesProperty], [EmbeddedProperty] and [EmbeddedMapProperty]: