Datomic - working with OR clause

I am currently working on porting my clojure application (with poop) to the Datomic framework and was in a loop when I translated requests. I understand that queries are not completely flexible (compared to korma), for example, I would like to evaluate conditional sentences around different variables.

Given the korma request,

(select users (where (or (and {:first_name [= "user"]} {:last_name [= "sample"]}) {:email [= " user.sample@email.com "]}))) 

can it be converted to datomic, with something like this?

  [:find ?e :where (or (and [?u :user/first-name "user"] [?u :user/last-name "sample"]) [?u :user/email " user.sample@email.com "]) 

but this is not recommended for queries (according to the Datomic docs), since all sentences used in a sentence or must use the same set of variables. How to set an OR clause for different sets of variables?

+5
source share
2 answers

Your request should work. All your sentences use the same variable ?u

 (d/q '[:find ?u :where (or (and [?u :user/first-name "user"] [?u :user/last-name "sample"]) [?u :user/email " user.sample@email.com "])] [[1 :user/first-name "user"] [1 :user/last-name "sample"] [2 :user/email " user.sample@email.com "] [3 :user/first-name "user"] [3 :user/last-name "not sample"]]) => #{[1] [2]} 

If you need to use different variables, you can use or-join to list them explicitly:

 (d/q '[:find ?u :in $ ?first-name ?last-name ?email :where (or-join [?u ?first-name ?last-name ?email] (and [?u :user/first-name ?first-name] [?u :user/last-name ?last-name]) [?u :user/email ?email])] [[1 :user/first-name "user"] [1 :user/last-name "sample"] [2 :user/email " user.sample@email.com "] [3 :user/first-name "user"] [3 :user/last-name "not sample"]] "user" "sample" " user.sample@email.com ") => #{[1] [2]} 
+5
source

This is very similar to this question:

SQL LIKE statement in datomic

You need to check the request rules.

http://docs.datomic.com/query.html

Your request will look something like this (untested!)

 (let [rules '[[(find-user ?user ?fname ?lname ?email) [?user :user/first-name ?fname] [?user :user/last-name ?lname]] [(find-user ?user ?fname ?lname ?email) [?user :user/email ?email]]]] (:find ?user :in $ % ?fname ?lname ?email :where (find-user ?user ?fname ?lname ?email) conn rules "user" "sample" " user.sample@email.com ")) 
0
source

All Articles