Querying Basics
Before we continue, let's take a closer look at the data model powering our Pokemon database.
Each Pokemon is stored as an Entity. Here is what Bulbasaur looks like:
Each key is an Attribute (:pokemon/name, :stat/speed, etc) and each value is the Value for that attribute on this entity (Bulbasaur, 45, etc).
In Datomic, every entity is assigned a unique entity ID. Let's find Bulbasaur's:
Now that we have the concept of an entity ID, we can flip the query around and ask: what Attributes does this entity have? We bind the attribute position to a logic variable, then resolve its human-readable name via :db/ident:
The underscore _ in the third position is a wildcard, it matches any value but does not bind it to a variable.
Finally, we can pull all attribute-value pairs at once by binding the value position too:
This works because of Datomic's Universal Schema. Every fact in the database is stored following this Entity-Attribute-Value structure. Attributes are themselves entities, which is why we can traverse from ?attribute-id to :db/ident to get the keyword name.
Try changing "Bulbasaur" to another Pokemon name in the queries above.
Take a look at the EDN file defining all of the Pokemon in our database.
Run the last query with a dual-typed Pokemon like "Charizard" and observe how many attribute-value rows appear — one for each fact stored about that entity.