Простая обратная навигация в Datomic - PullRequest
1 голос
/ 08 января 2020

Изучение Датоми c и проблемы с базовым c делом. Учитывая простую схему, содержащую:

: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.
]

Я хочу сделать Обратной навигации, чтобы найти "все клубы" Алексей "находится в". Если я сделаю это, я получу только один клуб:

d/q '[:find (pull ?g [ {:club/_members [:club/name]}]) 
       :in $ 
       :where 
       [?g :person/name "alexei"]
       ]
     (d/db conn))

Я ожидаю получить два удара для данных этого примера. Я моделирую это назад? Нужно ли создавать отдельную сущность для express человек в клубе?

Большое спасибо!

1 Ответ

2 голосов
/ 12 января 2020

Я также изучаю Datomi c, в настоящее время я использую 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
  • Вектор членов клуба в ваших данных выглядит так, как будто он смешивается [ { Я думаю, что вам нужно вектор двух карт там

Но эти проблемы могут отсутствовать в вашем исходном коде, могут быть устранены, если вы хотите поделиться своим исходным кодом

Надеюсь, это поможет

...