2015-05-20 15 views
5

我目前正在将我的clojure应用程序(使用korma)迁移到Datomic框架,并在翻译查询时处于循环状态。我意识到查询不是完全灵活的(与科尔玛相比),例如我想评估不同变量的条件子句。Datomic - 使用OR子句

考虑科尔马查询,

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

这可以转换为Datomic,像这样的东西?

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

但这不是查询(根据Datomic文档),如在一个或子句中使用必须使用相同的一组变量的所有条款的推荐的方式。我如何围绕不同的变量集设置OR子句?

回答

5

您的查询应该可以正常工作。您的所有条款使用相同的变量:?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]} 

如果你需要他们使用不同的变量,你可以使用or-join明确的列出它们:

(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]} 
+0

'(d/Q“[(未经测试!):寻找ú :??在$第一,最后所名名字?电子邮件 :其中(或(和[?u:用户/名字?名字] [?:用户/姓氏?姓氏]) [?u:user/email?email ])]' 在这种情况下不起作用,因为变量是不同的ent –

+0

我更新了该场景的答案。 –

0

这是非常相似的这个问题:

SQL LIKE operator in datomic

您需要检查查询规则

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

您的查询看起来东西这样

(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" "[email protected]"))