2015-05-20 6 views
5

Ich arbeite derzeit an der Migration meiner Clojure-App (mit Korma) zu Datomic-Framework und war in einer Schleife, während ich die Abfragen übersetzte. Ich weiß, dass die Abfragen nicht vollständig flexibel sind (im Vergleich zu Korma), zum Beispiel möchte ich bedingte Klauseln um verschiedene Variablen bewerten.Datomic - Arbeiten mit OR-Klausel

Unter Berücksichtigung einer Korma Abfrage

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

dies kann wie folgt mit etwas Datomic, umgewandelt werden?

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

aber dies ist nicht der empfohlene Weg (nach Datomic docs) abzufragen, da alle Klauseln in einem oder Klausel verwendet werden, müssen den gleichen Satz von Variablen verwenden. Wie lege ich eine OR-Klausel um verschiedene Variablengruppen fest?

Antwort

5

Ihre Abfrage sollte funktionieren. tun die gleiche Variable verwenden, um alle Ihre Klauseln: ?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]} 

Wenn Sie sie benötigen verschiedene Variablen zu verwenden, Sie or-join explizit verwenden können, um aufzulisten:

(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‚[(ungetestet!): Finden u :? In $ first-name letzt Name? E-Mail : wo (oder (und [? u: Benutzer/Vorname? Vorname] [? u: Benutzer/Nachname? Nachname]) [? u: user/email? email ]]] ' würde in diesem Fall nicht funktionieren, da die Variablen unterschiedlich sind ent –

+0

Ich aktualisierte die Antwort für dieses Szenario. –

0

Diese sehr ähnlich ist diese Frage:

SQL LIKE operator in datomic

Sie müssen überprüfen Abfrage Regeln.

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

Ihre Anfrage aussehen würde etwas wie diese

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