I am looking for feedback on an approach to modeling relationships specific to many in Datomic.
Problem
Suppose I want to create a Datomic scheme for a domain where Man has a list of favorite films. For example, Johnyour favorite films: Gladiator, Star Warsand Fight Club.
The most obvious scheme for modeling this in Datomic is the power attribute - a lot, for example:
["John" :person/favorite-movies "Star Wars"]
["John" :person/favorite-movies "Fight Club"]}
This approach makes it easy to add or remove movies from the list (just use :db/addand :db/retract), but I find it impractical to reset the entire list of films - you essentially need to calculate the difference between the old and the new, and it should work as a transaction function. This gets even worse when list items are not scalars.
Alternative approach
As an alternative approach, I am considering introducing indirection using a given object:
#{["John" :person/favorite-movies 42]
[42 :set.string/contains "Gladiator"]
[42 :set.string/contains "Star Wars"]
[42 :set.string/contains "Fight Club"]}
With this approach :person/favorite-movies, this is a power indicator, one, the ref-typed attribute, and :set.string/containsa multi-valued attribute with a string. Resetting the list is just a matter of creating a new set object:
[{:db/id "John"
:person/favorite-movies {:db/id (d/tempid :db.part/user)
:set.string/contains ["Gladiator"
"The Lord of the Rings"
"A Clockwork Orange"
"True Romance"]}}]
Are the limitations of this approach for modeling all-to-many relationships known?
Edit: less trivial use case
, , -, ref-typed Datomic.
, 'reset' , " ".
: , Answer Question, Option s. Answer Question. Answer - Option.
:
:answer/id: (, ):option/id: (-, ):answer/selectedOptions (ref-typed, cardinality-many)