Find Specifications

Every query so far has used the default :find form, which returns a set of tuples. Datomic Datalog offers four distinct find specifications, each returning a different shape. Choosing the right one makes downstream code simpler.

Relation (default) — set of tuples

The standard form. Each variable becomes a column; each matching combination becomes a row. Order within the set is not guaranteed.

[:find ?name ?speed :where [?e :pokemon/name ?name] [?e :stat/speed ?speed] [(> ?speed 100)]]

Collection — flat vector of one variable

Wrap a single variable in [?var ...] to get a flat vector of its values instead of a set of single-element tuples. Useful when you only care about one column and want to pass it directly to other code:

[:find [?name ...] :where [?e :pokemon/name ?name] [?e :stat/speed ?speed] [(> ?speed 100)]]

Scalar — single value

Append . after the variable to return exactly one value instead of a collection. When multiple rows match, which one you get is arbitrary — so scalars are most useful with aggregations that already produce a single row, like (max ...):

[:find (max ?speed) . :where [?e :stat/speed ?speed]]

Without the . this would return #{[110]} — a set containing one single-element tuple. With it you get the bare number 110.

Tuple — single row

Wrap multiple variables in [?a ?b] (no ...) to return exactly one tuple. Like the scalar form, it is most reliable when the query is guaranteed to match one row — for example, a lookup by a unique attribute:

[:find [?number ?type ?speed] :where [?e :pokemon/name "Pikachu"] [?e :pokemon/number ?number] [?e :pokemon/type ?type] [?e :stat/speed ?speed]]

Pikachu has exactly one entry in the database so this is safe. The result is a plain vector ["025" "Electric" 90] rather than a set of tuples — easy to destructure directly in Clojure.

Try: Use the tuple find spec to look up a different Pokemon — try "Mewtwo" or "Snorlax". Or combine the scalar spec with (min ?speed) to return just the single lowest speed value in the Pokedex.

Previous