-
-
Save stathissideris/201c1935a7960ec385fe to your computer and use it in GitHub Desktop.
Datomic queries against Clojure collections
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
;; Datomic example code | |
(use '[datomic.api :only (db q) :as d]) | |
;; ?answer binds a scalar | |
(q '[:find ?answer :in ?answer] | |
42) | |
;; of course you can bind more than one of anything | |
(q '[:find ?last ?first :in ?last ?first] | |
"Doe" "John") | |
;; [?last ?first] binds a tuple | |
(q '[:find ?last ?first :in [?last ?first]] | |
["Doe" "John"]) | |
;; [?first ...] binds a collection | |
(q '[:find ?first | |
:in [?first ...]] | |
["John" "Jane" "Phineas"]) | |
;; [[?first ?last]] binds a relation | |
(q '[:find ?first | |
:in [[?first ?last]]] | |
[["John" "Doe"] | |
["Jane" "Doe"]]) | |
;; a database binding name starts with $ instead of ? | |
;; any relation with 4-tuples E/A/V/T can act as a database | |
;; so in Datomic, you can mock a database with a list of lists | |
(q '[:find ?first | |
:in $db | |
:where [$db _ :firstName ?first]] | |
[[1 :firstName "John"]]) | |
;; same as previous, but omit $db for single-database query | |
;; any relation with 4-tuples eavt can act as a database | |
(q '[:find ?first | |
:where [_ :firstName ?first]] | |
[[1 :firstName "John" 42] | |
[1 :lastName "Doe" 42]]) | |
;; simple in-memory join, two tuple bindings | |
(q '[:find ?first ?height | |
:in [?last ?first ?email] [?email ?height]] | |
["Doe" "John" "[email protected]"] | |
["[email protected]" 71]) | |
;; simple in-memory join, two relation bindings | |
;; see next example for a faster approach | |
(q '[:find ?first ?height | |
:in [[?last ?first ?email]] [[?email ?height]]] | |
[["Doe" "John" "[email protected]"] | |
["Doe" "Jane" "[email protected]"]] | |
[["[email protected]" 73] | |
["[email protected]" 71]]) | |
;; same as previous example, but with database expressions | |
;; runs faster than relation bindings (as of July 2012) | |
(q '[:find ?first ?height | |
:in $a $b | |
:where [$a ?last ?first ?email] | |
[$b ?email ?height]] | |
[["Doe" "John" "[email protected]"] | |
["Doe" "Jane" "[email protected]"]] | |
[["[email protected]" 73] | |
["[email protected]" 71]]) | |
;; simple in-memory join, two database bindings | |
(q '[:find ?first ?height | |
:in $db1 $db2 | |
:where [$db1 ?e1 :firstName ?first] | |
[$db1 ?e1 :email ?email] | |
[$db2 ?e2 :email ?email] | |
[$db2 ?e2 :height ?height]] | |
[[1 :firstName "John"] | |
[1 :email "[email protected]"] | |
[2 :firstName "Jane"] | |
[2 :email "[email protected]"]] | |
[[100 :email "[email protected]"] | |
[100 :height 73] | |
[101 :email "[email protected]"] | |
[101 :height 71]]) | |
;; compare to http://stackoverflow.com/questions/3717939/iterating-and-processing-an-arraylist | |
(q '[:find ?car ?speed | |
:in [[?car ?speed]] | |
:where [(> ?speed 100)]] | |
[["Stock" 225] | |
["Spud" 80] | |
["Rocket" 400] | |
["Stock" 225] | |
["Clunker" 40]]) | |
;; compare to http://stackoverflow.com/questions/109383/how-to-sort-a-mapkey-value-on-the-values-in-java | |
(->> (q '[:find ?k ?v | |
:in [[?k ?v] ...]] | |
{:D 67.3 :A 99.5 :B 67.4 :C 67.5}) | |
(sort-by second)) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment