Optimizing your experience
Gradient background

Datomic Cheat Sheet Series - Queries (Part 3) - Rules

Clarice Bouwer

Software Engineering Team Lead and Director of Cloudsure

Thursday, 20 September 2018 · Estimated 1 minute read

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.

Relationship diagram

Create a database connection

Create an inline database connection

Copy
(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

Copy
(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

Copy
(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"]
;   ...}
Copy
(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]}
Copy
(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]
;  ...}