I'm currently working on migrating my clojure app(with korma) to Datomic framework and been in a loop while I was translating the queries. I realise the queries are not completely flexible(compared to korma), for example i would like to evaluate conditional clauses around different variables.
Considering a korma query,
(select users
(where (or (and {:first_name [= "user"]}
{:last_name [= "sample"]})
{:email [= "[email protected]"]})))
this can 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 "[email protected]"])
but this is not the recommended way of querying(according to Datomic docs), as all clauses used in an or clause must use the same set of variables. How do I set an OR clause around different sets of variables?
Your query should work. All of your clauses do 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 "[email protected]"])]
[[1 :user/first-name "user"]
[1 :user/last-name "sample"]
[2 :user/email "[email protected]"]
[3 :user/first-name "user"]
[3 :user/last-name "not sample"]])
=> #{[1] [2]}
If you need them to use different variables, you can use or-join
to explicitly list them:
(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 "[email protected]"]
[3 :user/first-name "user"]
[3 :user/last-name "not sample"]]
"user"
"sample"
"[email protected]")
=> #{[1] [2]}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With