Fork me on GitHub
#xtdb
<
2023-06-07
>
Dameon14:06:07

Is it possible to parameterize the predicate functions used in queries? I have a pretty large query (100+ lines with multiple subqueries) that will only differ by one custom predicate function, for several different use cases. Ideally I wouldn’t have to maintain 3-4 identical copies of this large query. Example:

(defn my-q [node predicate]
  (xt/q (xt/db node)
    {:find '[a]
     :where ['[a :some-key ?b]
             [(predicate '?b)]]}))

(my-q my-node 'lib/predicate-1)
(my-q my-node 'lib/predicate-2)
(my-q my-node 'lib/predicate-3)

jarohen14:06:42

hey @U03DWT00WUB 👋 try a list call?

(defn my-q [node predicate]
  (xt/q (xt/db node)
    {:find '[a]
     :where ['[a :some-key ?b]
             [(list predicate '?b)]]}))

Dameon14:06:41

That worked! Do you know why that works specifically? I didn’t see anything like that in the docs.

Dameon14:06:49

Oh, I guess it’s because closure would try to evaluate (predicate ’b).

jarohen14:06:22

yep, exactly that - XT queries are just data structures, so you could temporarily check what you're passing either with a doto-prn or even just returning the data structure instead, checking it at the REPL (as you were above) then putting it back:

(defn my-q [node predicate]
  (xt/q (xt/db node)
    (doto {:find '[a]
           :where ['[a :some-key ?b]
                   [(list predicate '?b)]]}
      prn)))
(defn my-q [node predicate]
  {:find '[a]
   :where ['[a :some-key ?b]
           [(list predicate '?b)]]})

Dameon14:06:43

Awesome, this is all very helpful, thank you.

🙏 2