Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Using a database function in a datomic query

Tags:

datomic

I'm trying to do an 'outer join' in Datomic via the REST API. From https://github.com/Datomic/day-of-datomic/blob/master/tutorial/social_news.clj I have taken the final example:

(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))

I inserted the maybe function into my database, and it can be queried thus:

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

returns

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

However, I am unable to work out how to call the function in a query. I have an :data/user attribute on some transactions, which I want to get the value for where it exists. Here's the query I'm trying to run; I would like :maybe to be the database function defined above.

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

I'm pretty sure I'm missing something pretty obvious, but I've been stuck on this for a day now. Thanks for any help!

like image 217
grahamstratton Avatar asked Sep 18 '12 09:09

grahamstratton


2 Answers

You need to use d/invoke. So your example would look like this:

[: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]]
like image 114
Brian Avatar answered Nov 08 '22 05:11

Brian


According to the Query Doc of Datomic, you can use any pure function in queries. You don't have to install them first. Functions you have to install are transaction functions.

Query functions don't need to be installed because they run in your application like all other functions. Datomic has nothing like a database server that executes queries. Queries are always executed in your application by the Peer Library.

The only type of functions you need to install are transaction functions because they run inside the Transactor. The Transactor is a single, special process that handles all the writes in Datomic.

like image 23
Alexander Kiel Avatar answered Nov 08 '22 05:11

Alexander Kiel