Использование функции базы данных в двухатомном запросе

Я пытаюсь сделать "внешнее соединение" в Datomic через REST API. Из https://github.com/Datomic/day-of-datomic/blob/master/tutorial/social_news.clj я взял последний пример:

(defn maybe
  "Returns the set of attr for e, or nil if e does not possess
   any values for attr."
  [db e attr]
  (seq (map :a (d/datoms db :eavt e attr))))

;; find all users 
(q '[:find ?e ?upvote
     :where
     [?e :user/email]
     [(user/maybe $ ?e :user/upVotes) ?upvote]]
   (db conn))

Я вставил функцию Maybe в свою базу данных, и ее можно запросить следующим образом:

[:find ?n ?v :in $ :where [?e ?a ?v] [?a :db/ident :db/fn] [?e :db/ident ?n]]

возвращается

:maybe  #db/fn{:code "(seq (map :a (d/datoms db :eavt e attr)))", :params [db e attr], :requires [], :imports [], :lang :clojure}

Однако я не могу понять, как вызвать функцию в запросе. у меня есть :data/user атрибут для некоторых транзакций, который я хочу получить значение, где он существует. Вот запрос, который я пытаюсь выполнить; мне бы хотелось :maybe быть функцией базы данных, определенной выше.

[:find ?attr ?v ?when ?who :where
 [17592186045423 ?a ?v ?tx true]
 [?a :db/ident ?attr]
 [(:maybe $ ?tx :data/user) ?who]
 [?tx :db/txInstant ?when]]

Я почти уверен, что упускаю что-то довольно очевидное, но я застрял на этом целый день. Спасибо за любую помощь!

2 ответа

Решение

Вам нужно использовать d/invoke. Итак, ваш пример будет выглядеть так:

[:find ?attr ?v ?when ?who :where
 [17592186045423 ?a ?v ?tx true]
 [?a :db/ident ?attr]
 [(d/invoke $ :maybe ?tx :data/user) ?who]
 [?tx :db/txInstant ?when]]

Согласно Query Doc Datomic, вы можете использовать любую чистую функцию в запросах. Вам не нужно устанавливать их в первую очередь. Функции, которые вы должны установить, являются функциями транзакций.

Функции запросов не нужно устанавливать, потому что они запускаются в вашем приложении, как и все другие функции. Datomic не имеет ничего общего с сервером базы данных, который выполняет запросы. Запросы всегда выполняются в вашем приложении Peer Library.

Единственный тип функций, который вам нужно установить, это функции транзакций, потому что они выполняются внутри Transactor. Transactor - это отдельный специальный процесс, который обрабатывает все записи в Datomic.

Другие вопросы по тегам