Datomic Cheat Sheet Series - Queries (Part 3) - Rules
Software Engineering Team Lead and Director of Cloudsure
In this post I work through the creation of rules using the Datomic MusicBrainz sample database. The example queries are grabbed from the Datomic Docs and the Datomic mbrainz sample GitHub pages. If you want to get started with Datomic, check out the first post in the series. If you want to see other queries, then check out part 1 and part 2.
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))
Rules are a named group of clauses that can be used to create reusable logical components that can be slotted into multiple :where
clauses. This binds portions of the query's logic at query time.
Create rules
(def rules ' [[(track-name ?e ?t)
[?e :track/name ?t]]])
(d/q '[:find ?e ?artist-name ?track-name
:in $ % ?track-name
:where
(track-name ?e ?track-name)
[?e :track/artists]
[?a :artist/name ?artist-name]] db rules "Can't Find a Reason")
; =>
; #{[17592186149695 "McCully Workshop" "Can't Find a Reason"]
; [17592186149685 "Love" "Can't Find a Reason"]
; [17592186149685 "Bakerloo" "Can't Find a Reason"]
; ...}
(def rules ' [[(track-name ?e ?t)
[?e :track/name ?t]]])
(d/q '[:find ?e ?track-name ?duration
:in $ % ?track-name
:where
(track-name ?e ?track-name)
[?e :track/duration ?duration]] db rules "Can't Find a Reason")
; => #{[17592186149695 "Can't Find a Reason" 271506]
; [17592186149685 "Can't Find a Reason" 270573]}
(def rules ' [[(track-release ?t ?r)
[?m :medium/tracks ?t]
[?r :release/media ?m]]])
(d/q '[:find ?title ?album ?year
:in $ % ?artist-name
:where
[?a :artist/name ?artist-name]
[?t :track/artists ?a]
[?t :track/name ?title]
(track-release ?t ?r)
[?r :release/name ?album]
[?r :release/year ?year]] db rules "John Lennon")
;=>
;#{["Yer Blues" "Live Peace in Toronto 1969" 1969]
; ["Isolation" "John Lennon/Plastic Ono Band" 1970]
; ["Open Your Box" "Power to the People" 1971]
; ...}