Datomic find spec syntax by example

Here are the official docs for Find Specifications

Here is an interactive hyperfiddle if you want to type along for practice. (Hyperfiddle editing is presently login-walled for security, so you'll need to login to play, sorry.)

Find Relation

[:find ?e ?name ; dimension 2 :where [?e :neighborhood/name ?name]] #{[17592186045522 "Admiral (West Seattle)"] [17592186045564 "Broadview"] [17592186045528 "Belltown"] [17592186045524 "Alki"] [17592186045551 "Beacon Hill"] [17592186045536 "Ballard"]} "Relations" are the basic building block. Relations come out as tuples.

Find Relation, dimension = 1

[:find ?name ; dimension = 1 :where [?e :neighborhood/name ?name]] #{["Belltown"] ["Ballard"] ["Alki"] ["Broadview"] ["Beacon Hill"] ["Admiral (West Seattle)"]} Note the useless wrapper tuple. The :find relation had only one element so the tuple dimension = 1.

If relation dimension = 1, we can flatten the annoying tuple:

[:find [?e ...] :where [?e :neighborhood/name ?name]] ["Belltown" "Ballard" "Alki" "Broadview" "Beacon Hill" "Admiral (West Seattle)"] Find Relation, tuple dimension = 1

What if the collection's row count = 1?

(A rather dumb query but it's just an example.)

[:find ?e ?name :where [?e :neighborhood/name ?name] [(= ?name "Ballard")]] #{[17592186045536 "Ballard"]} Note the outer collection wrapper with only one relation. We asked for all the relations and there is only one.

It's worse if there is only one find element

[:find ?name :where [?e :neighborhood/name ?name] [(= ?name "Ballard")]] #{["Ballard"]} a collection (count=1) of relations (dimension=1)

Indicate there is only one row

[:find [?e ?name] :where [?e :neighborhood/name ?name] [(= ?name "Ballard")]] [17592186045536 "Ballard"] Elide the row collection, we just want one tuple

Or unwrap all the way to a scalar