article · #69
Datomic Cheat Sheet Series - Queries (Part 1)
Clarice Bouwer
Software Engineering Team Lead and Director of Cloudsure
Saturday, 15 September 2018 · Estimated 2 minute read
In this post I work through querying the Datomic MusicBrainz sample database. The example queries are grabbed from the Datomic Docs. If you want to get started with Datomic, check out the previous post in the series.
Create a new project
lein new beryllium
vi beryllium/project.clj # use your favorite editor
# add the following snippet to your project.clj file
:dependencies [[org.clojure/clojure "1.9.0"]
[com.datomic/datomic-pro "0.9.5703"]]
:repositories [["my.datomic.com" {:url "https://my.datomic.com/repo"
:username "<username>"
:password "<uuid>"}]]
lein repl
# Exit with CTRL + D
Get your credentials from your My Datomic Account.
Create a database connection
Create an inline database connection
(require '[datomic.api :as d])
(def db-uri "datomic:dev://localhost:4334/mbrainz-1968-1973")
(def conn (d/connect db-uri))
(def db (d/db conn))
Create a database connection as a function
(ns beryllium.core
(:require [datomic.api :as d]))
(defn new-db []
(let [db-uri "datomic:dev://localhost:4334/mbrainz-1968-1973"
conn (d/connect db-uri)
db (d/db conn)]
db))
Query entities
(d/q '[:find ?e
:where [?e :track/name]] db)
;=> #{[17592186050536]
; [17592186050537]
; [17592186050538]
; ...}
(d/q '[:find [?e ...]
:where [?e :track/name]] db)
;=> [17592186050536
; 17592186050537
; 17592186050538
; ...]
(d/q '[:find [(sample 10 ?e) ...]
:where [?e :track/name]] db)
;=> [[17592186052808
; 17592186070900
; 17592186170898
; ...]]
(def release (d/entity db 17592186089442))
(d/touch release)
;=> #:db{:id 17592186089442}
(def release (d/entity db 17592186089442))
(def media (:release/media release))
(map #(println (:medium/tracks %)) media)
;#{#:db{:id 17592186089445} #:db{:id 17592186089447} #:db{:id 17592186089444} #:db{:id 17592186089446}}
Get values from entities
(def release (d/entity db 17592186089442))
(:release/name release)
;=> "Banished Bridge"
(d/q '[:find ?release-name
:where [?e :release/name ?release-name]] db)
;=> #{["Osmium"]
; ["Hela roept de akela"]
; ["Ali Baba"]
; ...}
(d/q '[:find [?release-name ...]
:where [?e :release/name ?release-name]] db)
;=> ["Osmium"
; "Hela roept de akela"
; "Ali Baba"
; ...]
Multiple inputs (more)
(d/q '[:find [?release-name ...]
:in $ ?artist-name
:where
[?artist :artist/name ?artist-name]
[?release :release/artists ?artist]
[?release :release/name ?release-name]] db "John Lennon")
;=> ["Power to the People"
; "Unfinished Music No. 2: Life With the Lions"
; "Live Peace in Toronto 1969"
; ...]
Tuple binding (more)
(d/q '[:find [?release ...]
:in $ [?artist-name ?release-name]
:where
[?artist :artist/name ?artist-name]
[?release :release/artists ?artist]
[?release :release/name ?release-name]] db ["John Lennon" "Mind Games"])
;=> [17592186157686 17592186157672 17592186157690 17592186157658]
Collection binding (more)
(d/q '[:find [?release-name ...]
:in $ [?artist-name ...]
:where
[?artist :artist/name ?artist-name]
[?release :release/artists ?artist]
[?release :release/name ?release-name]] db ["Paul McCartney" "George Harrison"])
;=> ["My Sweet Lord"
; "Electronic Sound"
; "Give Me Love (Give Me Peace on Earth)"
; ...]
Relation binding (more)
(d/q '[:find [?release ...]
:in $ [[?artist-name ?release-name]]
:where
[?artist :artist/name ?artist-name]
[?release :release/artists ?artist]
[?release :release/name ?release-name]] db [["John Lennon" "Mind Games"]
["Paul McCartney" "Ram"]])
;=> [17592186157686 17592186157672 17592186157690 17592186157658 17592186063566]
Find specifications (more)
(d/q '[:find ?artist-name ?release-name
:where
[?release :release/name ?release-name]
[?release :release/artists ?artist]
[?artist :artist/name ?artist-name]] db)
;=> #{["George Jones" "With Love"]
; ["Shocking Blue" "Hello Darkness / Pickin' Tomatoes"]
; ["Junipher Greene" "Friendship"]
; ...}
(d/q '[:find [?year ?month ?day]
:in $ ?name
:where
[?artist :artist/name ?name]
[?artist :artist/startDay ?day]
[?artist :artist/startMonth ?month]
[?artist :artist/startYear ?year]] db "John Lennon")
;=> [1940 10 9]
(d/q '[:find ?year .
:in $ ?name
:where
[?artist :artist/name ?name]
[?artist :artist/startYear ?year]] db "John Lennon")
=> 1940