Fork me on GitHub
#xtdb
<
2023-07-10
>
richiardiandrea20:07:44

Hi there, I am trying to build a :where clause from a map of keys... Is there a way to do that? I am playing with :in and its bindings but I cannot really understand if I have to use :in for this

sergey.shvets23:07:32

Yes, you can build it programmatically. I have a program where I built my queries automatically. This is code that illustrates it:

(-> acc
 (update :in intov ['lower 'upper])
 (update :where intov ['[car :car/miles miles]
'[(< miles upper)]
'[(> miles lower)]])
 (update :params intov [lower upper])))
Where acc is a map that I build in reduce over parameters. The trick is to put ' before your vectors where you don't need to change them.

sergey.shvets23:07:18

this

'{:find [*] :where [a :b/id c]}
Equals to
{:find '[*] :where '[a :b/id c]}
And then you can use regular clojure functions to construct second map.

richiardiandrea15:07:36

I think I have managed, these is what I eventually drafted

(defn compute-criteria-in
  [searchable-keys search-criteria]
  (let [bindings (->>
                  searchable-keys
                  (into []
                        (comp (map (fn [search-key]
                                     ;; NOTE: we need find cause `nil`s are valid values and `get` would discard them
                                     (when (find search-criteria search-key)
                                       (symbol (str "?" (name search-key))))))
                              (filter some?))))]
    ;; DONT: we want an empty vector not [[]] if no bindings were computed
    (cond-> []
      (seq bindings) (conj bindings))))

sergey.shvets16:07:29

It should work. Also, you don't really need to have ? before symbol in the xtdb query. The question mark is a convention, so it's easier to read the query with eyes. If you autogenerate query, you can skip that. Just to make your code a tiny bit easier.

richiardiandrea17:07:56

yep sounds good thanks!

richiardiandrea20:07:21

it's a bit different from this I guess https://docs.xtdb.com/language-reference/1.23.3/datalog-queries/#_relation_binding Cause I have only one map of key-values