Fork me on GitHub
#xtdb
<
2021-08-25
>
henrik12:08:21

Regarding rules in Crux: the examples all show rules defined inline in the query. How can I pass a rule to a query in Crux, defined externally from the query?

tatut12:08:08

(crux/q db (assoc {:find ...} :rules external-rule-collection)) ?

👍 3
tatut12:08:18

I would expect as it's just data

henrik12:08:16

Simple, elegant, I like it.

refset12:08:05

Yep, that's the right answer. Crux doesn't support parametrisation of rules via :in (since they must be known ahead of time, for query compilation)

henrik13:08:56

Perfect, I just don't want to copy and paste the same 30 line rule into every query.

🙂 6
sheluchin15:08:25

I have this test snippet:

(let [node db.mounts/crux-node
        e1 {:crux.db/id {:e/id 1}
            :e/id 1
            :e/d-id {:d/id 99}}
        ;; get d1 but also show that e1 points at it
        d1 {:crux.db/id {:d/id 99}
            :d/id 99}]
    (crux/await-tx node
      (crux/submit-tx node [[:crux.tx/put e1]]))
    (crux/await-tx node
      (crux/submit-tx node [[:crux.tx/put d1]]))
    (prn
      (crux/q (crux/db node)
        '{:find [(pull d [:d/id
                          {(:e/_d-id {:as :e/id :cardinality :one}) [:e/id]}])]
          :where [[d :d/id 99]]})))
It prints:
#{[{:d/id 99, :e/id #:e{:id 1}}]}
I would like for it to print:
#{[{:d/id 99, :e/id 1}]}
Is it possible without using Clojure to reshape the result?

jarohen15:08:18

for the example above, you might be better off using a vanilla query without pull, given you have a flat result - instead opting for :keys:

(crux/q (crux/db node)
        '{:find [d-id e-id]
          :in [d-id]
          :keys [d/id e/id]
          :where [[d :d/id d-id]
                  [e :e/d-id d]
                  [e :e/id e-id]]}
        99)

;; => #{{:d/id 99, :e/id 1}}

sheluchin15:08:21

Is there a way to provide a default value using vanilla queries the same way that's possible with pull? I have an entity with an optional field and I'd like to query for all those documents regardless of whether the optional field is present or not.

jarohen15:08:17

Is it the ID relationship that's optional? if not, you could consider adding more pull clauses to the :find to achieve something similar

jarohen15:08:05

(crux/q (crux/db node)
        '{:find [(pull d [:d/id]) (pull e [:e/id])]
          :in [d-id]
          :keys [d e]
          :where [[d :d/id d-id]
                  [e :e/d-id d]
                  [e :e/id e-id]]}
        99)

;; => #{{:d {:d/id 99}, :e {:e/id 1}}}

sheluchin15:08:49

Thanks, I think that gives me enough to work with.

🙏 3