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
  • 你的数据中的俱乐部成员向量看起来像是在混合 [ { 我认为你需要一个包含两个地图的向量

但这些问题可能不在您的源代码中,如果您想共享您的源代码,可以进一步调试

希望对您有所帮助