-
-
Save thickey/3827215 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" "jdoe@example.com"] | |
["jdoe@example.com" 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" "jdoe@example.com"] | |
["Doe" "Jane" "jane@example.com"]] | |
[["jane@example.com" 73] | |
["jdoe@example.com" 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" "jdoe@example.com"] | |
["Doe" "Jane" "jane@example.com"]] | |
[["jane@example.com" 73] | |
["jdoe@example.com" 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 "jdoe@example.com"] | |
[2 :firstName "Jane"] | |
[2 :email "jane@example.com"]] | |
[[100 :email "jane@example.com"] | |
[100 :height 73] | |
[101 :email "jdoe@example.com"] | |
[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