Reputation: 35
Learning Datomic, and having trouble with a basic case. Given a simple schema containing:
:club/name
:club/members (ref, cardinality many)
and
:people/name
So it might be populated (basically) like this:
[
{:club/name "Carpentry" :club/members [:person/name "liliana" :person/name "alexei"}]}
{:club/name "Taxidermy" :club/members [:person/name "karenna" :person/name "alexei"}]}
etc.
]
I want to do a reverse navigation to find "all the clubs 'alexei' is in". If I do this, I get only one club:
d/q '[:find (pull ?g [ {:club/_members [:club/name]}])
:in $
:where
[?g :person/name "alexei"]
]
(d/db conn))
I would expect to get two hits for this example data. Am I modeling it backwards? Do I have to create a separate entity to express person-in-club?
Thanks much!
Upvotes: 2
Views: 298
Reputation: 1953
I'm learning Datomic too, currently, I'm using Datahike because the syntax is similar & easier to dev on imo
Anyway I tried your example and came up with this:
(ns club
(:require [datahike.api :as d]))
(def schema
[{:db/ident :person/name
:db/valueType :db.type/string
:db/cardinality :db.cardinality/one}
{:db/ident :club/name
:db/valueType :db.type/string
:db/cardinality :db.cardinality/one}
{:db/ident :club/members
:db/valueType :db.type/ref
:db/cardinality :db.cardinality/many}])
(def database "datahike:mem://example")
(def data
[{:club/name "Carpentry" :club/members [{:person/name "liliana"} {:person/name "alexei"}]}
{:club/name "Taxidermy" :club/members [{:person/name "karenna"} {:person/name "alexei"}]}])
(comment
(d/create-database database)
(def conn (d/connect database))
(d/transact conn schema)
(d/transact conn data)
(d/q '[:find (pull ?e [{:club/_members [:club/name]}])
:where [?e :person/name "alexei"]]
@conn))
Result:
([#:club{:_members [#:club{:name "Carpentry"}]}] [#:club{:_members [#:club{:name "Taxidermy"}]}])
Which I think is what you were looking for
There are two things that stand out to me in your comment that might have caused issue:
people/name
but your data says person/name
[
{
I think you need a vector of two maps in thereBut those issues might not be in your source code, could debug further if you'd like to share your source code
Hope this helps
Upvotes: 3