In docs example,
(transact conn [{:db/id -1
:name "Oleg"
:_friend 296}])
;; equivalent to
(transact conn [[:db/add -1 :name "Oleg"]
[:db/add 296 :friend -1]])
This would mean db registers that Ivan, 296, considers Oleg a friend (`[:db/add 296 :friend -1]`) but not necessarily that Oleg considers Ivan a friend. 🥲 Would that be correct interpretation of assertions of the db?the :_friend part won't really appear in the schema; it's not a real attribute. it's implicit, since every :db.type/ref attribute can be considered both forwards (by its actual :db/ident, eg. :friend) and backwards (with the leading underscore, :_friend).
as to whether it's worth specifying refs even when you'd prefer to avoid schema, I think it's absolutely worth the effort.
compare with DataScript, which is in-memory and so doesn't need to care about value types: it still supports :db.type/ref! knowing the number is a ref enables a lot of powerful things, such as transacting nested maps.
(transact conn [{:some/value "foo", :something/nested {:nested/value 12}}]) will create two entities, something like this:
300 :some/value "foo"
300 :something/nested 301
301 :nested/value 12all refs are indexed in both directions, but two-way relationships are sometimes useful anyway. by convention the reverse relationship is spelled :_friend.
note that even if the forward relationship is :cardinality/one, the reverse is always :cardinality/many, because there's no limit to how many other entities might point their single at a given entity.
it's a more natural fit for "follows" relationships than symmetrical ones like friendship.
If I understand, (transact conn [[:db/add -1 :name "Oleg"][:db/add 296 :friend -1]]) produces in EAV form something like:
301 :name "Oleg"
301 :friend 296
296 :_friend 301
I am using :schema-flexibility :read and so, during the tx above, somehow the following schema is inferred and transacted as something like:
[{:db/ident :friend
:db/valueType :db.type/ref
:db/index true
:db/cardinality :db.cardinality/one}
{:db/ident :_friend
:db/valueType :db.type/ref
:db/index true
:db/cardinality :db.cardinality/many}]
Is that about right?Because I am extremely lazy (and work alone) I am trying to understand how to avoid defining schema as much as possible while still producing the right "relationships" needed for EAV.
Generally, I dislike using db.type/ref but I guess this is the only way db knows it is looking at a reference rather than a primitive Numeric?
(I am trying to understand if the assertion creates a "two-way" [or "reciprocal"] relationship or just a one-directional pointer.)