Fork me on GitHub
#xtdb
<
2021-05-26
>
Thomas Moerman08:05:30

Hi, i'm a bit stuck on writing a query that orders results on a field {:msg/read-on <a date>} that might not exist in a document. How should i go about this?

Thomas Moerman09:05:09

For now I break up the query in two queries where one uses a not-join, I was wondering whether i can express this in one single query using Crux datalog.

jarohen09:05:55

Hey @U052A8RUT 👋 we tend to go one of two routes for this one: - if it's straightforward enough, add :msg/read-on nil when you index the documents - otherwise, the following pattern should help you:

;; docs
[[:crux.tx/put {:crux.db/id :foo}]
 [:crux.tx/put {:crux.db/id :bar, :value 2}]]

;; query
'{:find [?e ?value]
  :where [[?e :crux.db/id]
          (or [?e :value ?value]
              (and (not-join [?e] [?e :value])
                   [(identity nil) ?value]))]}

;; => #{[:bar 2] [:foo nil]}

Thomas Moerman09:05:17

Thank your very much! My datalog-fu is not yet black-belt, but I'm trying 😉

🙏 3
🥋 3
refset09:05:32

The other variation for this, which I personally find more readable, uses an or-join at the top level, see https://github.com/juxt/crux/blob/5b93a04259fdc078a8de8f1777084164abb795e5/crux-test/test/crux/query_test.clj#L1778-L1781 I'm not actually certain whether one might be better/faster than the other though :thinking_face:

👍 3