In the Datomic dialect: Datomic - Overview: Introduction

- In Datomic, a Datalog query is written in extensible data notation (edn). Edn is a data format similar to JSON, but it:

is extensible with user defined value types, has more base types, is a subset of Clojure data.

- Here is an example query that finds all movie titles in our example database:

[:find ?title :where [_ :movie/title ?title]] Note that the query is a vector with four elements:

the keyword :find the symbol ?title the keyword :where the vector [_ :movie/title ?title] Keyword: what you tell Datalog to do. Symbol: the variable you want outputted. Vector: a complex expression Datalog would make early Wittgenstein happy.

- The data model in Datomic is based around atomic facts called datoms. A datom is a 4-tuple consisting of

Entity ID Attribute Value Transaction ID Entity ID is the reference number of the fact. Attribute and value are a standard key:value pair. Transaction is when this info was uploaded to the database.

You can think of the database as a flat set of datoms of the form: [<e-id> <attribute> <value> <tx-id>] ... [ 167 :person/name "James Cameron" 102 ] [ 234 :movie/title "Die Hard" 102 ] [ 234 :movie/year 1987 102 ] [ 235 :movie/title "Terminator" 102 ] [ 235 :movie/director 167 102 ] ...

The entity ID can have multiple entries (ie, there can be multiple facts about a single entity.) Values can be entity IDs, such that "James Cameron" can be the director in the 9th line. A "pattern variable" is a symbol starting with ? ie ?title

- For example, this query finds all entity-ids that have the attribute :person/name with a value of "Ridley Scott":

common lisp [:find ?e :where [?e :person/name "Ridley Scott"]] Basic queries "A data pattern is a datom with some parts replaced with pattern variables." The data pattern is the stuff after where-- pv's are ?variable, they get swapped out for actual data-pieces to run the query. Underscore in a data pattern means "ignore this part of the data pattern" Data patterns are vectors. There can be more than one vector in a where clause.

- [:find ?title :where [?e :movie/year 1987] [?e :movie/title ?title]] The important thing to note here is that the pattern variable ?e is used in both data patterns. When a pattern variable is used in multiple places, the query engine requires it to be bound to the same value in each place. Therefore, this query will only find movie titles for movies made in 1987. Parameterized Queries To reuse queries regardless of their variables, use in instead of where:

//this [:find ?title :where [?p :person/name "Sylvester Stallone"] [?m :movie/cast ?p] [?m :movie/title ?title]] //turns into this [:find ?title :in $ ?name :where [?p :person/name ?name] [?m :movie/cast ?p] [?m :movie/title ?title]] //if we specify sylvester in the query

The $ means "the entire database" It seems like this kind of means-- search the whole database for the name I'm giving later (:in $ ?name), and then the where query, so there's like two queries in one The above query is executed like (q query db "Sylvester Stallone"), where query is the query we just saw, and db is a database value. You can have any number of inputs to a query. The database parameter is implicit most of the time, but the actual datapattern of every fact is: [<database> <entity-id> <attribute> <value> <transaction-id>] If you want, you can make a tuple to be used as your parameter. It can be destructured in your query:

[:find ?title :in $ [?director ?actor] :where [?d :person/name ?director] [?a :person/name ?actor] [?m :movie/director ?d] [?m :movie/cast ?a] [?m :movie/title ?title]]

Can also "spread operate" to find this OR that You can use collection destructuring to implement a kind of logical or in your query. Say you want to find all movies directed by either James Cameron or Ridley Scott:

[:find ?title :in $ [?director ...] :where [?p :person/name ?director] [?m :movie/director ?p] [?m :movie/title ?title]]

Relations Relations are a big deal. You can input external information and it will integrate with the info in the database. Example external info that gives us box office earnings for movie titles

[ ... ["Die Hard" 140700000] ["Alien" 104931801] ["Lethal Weapon" 120207127] ["Commando" 57491000] ... ]

To find out the earnings for each movie a given director has made:

[:find ?title ?box-office :in $ ?director ?title ?box-office :where [?p :person/name ?director] [?m :movie/director ?p] [?m :movie/title ?title]]