datomic 中的简单反向导航
Simple reverse navigation in datomic
正在学习 Datomic,在处理一个基本案例时遇到困难。给定一个包含以下内容的简单模式:
:club/name
:club/members (ref, cardinality many)
和
:people/name
所以它可能(基本上)像这样填充:
[
{:club/name "Carpentry" :club/members [:person/name "liliana" :person/name "alexei"}]}
{:club/name "Taxidermy" :club/members [:person/name "karenna" :person/name "alexei"}]}
etc.
]
我想进行反向导航以找到 "all the clubs 'alexei' is in"。如果我这样做,我只会得到一个俱乐部:
d/q '[:find (pull ?g [ {:club/_members [:club/name]}])
:in $
:where
[?g :person/name "alexei"]
]
(d/db conn))
对于这个示例数据,我希望得到两次匹配。我是在向后建模吗?我是否必须创建一个单独的实体来表达俱乐部中的人?
非常感谢!
我也在学习 Datomic,目前,我正在使用 Datahike,因为语法相似并且更容易在 imo 上开发
无论如何,我试过你的例子并想出了这个:
(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))
结果:
([#:club{:_members [#:club{:name "Carpentry"}]}] [#:club{:_members [#:club{:name "Taxidermy"}]}])
我认为这就是您要找的东西
在你的评论中有两件事对我来说很突出,可能会导致问题:
- 您的架构显示
people/name
但您的数据显示 person/name
- 你的数据中的俱乐部成员向量看起来像是在混合
[
{
我认为你需要一个包含两个地图的向量
但这些问题可能不在您的源代码中,如果您想共享您的源代码,可以进一步调试
希望对您有所帮助
正在学习 Datomic,在处理一个基本案例时遇到困难。给定一个包含以下内容的简单模式:
:club/name
:club/members (ref, cardinality many)
和
:people/name
所以它可能(基本上)像这样填充:
[
{:club/name "Carpentry" :club/members [:person/name "liliana" :person/name "alexei"}]}
{:club/name "Taxidermy" :club/members [:person/name "karenna" :person/name "alexei"}]}
etc.
]
我想进行反向导航以找到 "all the clubs 'alexei' is in"。如果我这样做,我只会得到一个俱乐部:
d/q '[:find (pull ?g [ {:club/_members [:club/name]}])
:in $
:where
[?g :person/name "alexei"]
]
(d/db conn))
对于这个示例数据,我希望得到两次匹配。我是在向后建模吗?我是否必须创建一个单独的实体来表达俱乐部中的人?
非常感谢!
我也在学习 Datomic,目前,我正在使用 Datahike,因为语法相似并且更容易在 imo 上开发
无论如何,我试过你的例子并想出了这个:
(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))
结果:
([#:club{:_members [#:club{:name "Carpentry"}]}] [#:club{:_members [#:club{:name "Taxidermy"}]}])
我认为这就是您要找的东西
在你的评论中有两件事对我来说很突出,可能会导致问题:
- 您的架构显示
people/name
但您的数据显示person/name
- 你的数据中的俱乐部成员向量看起来像是在混合
[
{
我认为你需要一个包含两个地图的向量
但这些问题可能不在您的源代码中,如果您想共享您的源代码,可以进一步调试
希望对您有所帮助