Использование функции базы данных в двухатомном запросе
Я пытаюсь сделать "внешнее соединение" в 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.