Raw Index Access
Most Datomic programs will not access the indexes directly, instead taking advantage of Datomic's declarative Datalog query engine.
However, raw index access is available for integrations. For example, you might use the indexes to make Datomic data available to a map/reduce framework spanning multiple data sources of different types.
Datomic indexes are covering indexes. This means the index actually contains the datoms, rather than just a pointer to them. When you (or a Datomic query) iterates an index, it gets the datoms themselves, without any additional lookup.
Datomic Indexes
Datomic automatically maintains four indexes. Each index sorts datoms in a specific order. These indexes are named based on the sort order used:
Index | Sort Order | Contains |
---|---|---|
EAVT | entity / attribute / value / tx | all datoms |
AEVT | attribute / entity / value / tx | all datoms |
AVET | attribute / value / entity / tx | all datoms |
VAET | value / attribute / entity / tx | all reference datoms |
EAVT Index
The EAVT index provides efficient access to everything about a given entity. Conceptually this is very similar to row access style in a SQL database, except that entities can possess arbitrary attributes rather than being limited to a predefined set of columns.
The example below shows all of the facts about entity 42 grouped together:
EAVT is also useful in master/detail lookups, since the references to detail entities are just ordinary Vs alongside the scalar attributes of the master entity. Better still, Datomic assigns entity ids so that when master and detail records are created in the same transaction, they will be colocated in EAVT.
Datomic's EAVT and VAET indexes can automatically navigate entity relationships in both directions, so you do not need to (and should not) create two attributes that model the same relationship but from different directions.
AEVT Index
The AEVT index provides efficient access to all values for a given
attribute, comparable to traditional column access style. In the table
below, notice how all :release/name
attributes are grouped together.
This allows Datomic to efficiently query for all values of the
:release/name
attribute, because the values reside next to one another
in the index.
AVET Index
The AVET index provides efficient access to particular combinations of
attribute and value, much like a key-value store. The example below
shows a portion of the AVET index allowing lookup by :release/name
.
The AVET index also supports the index-range
operation, which returns
all attribute values in a particular range. For more information about
index-range
, refer to the Datomic API documentation for your
programming language.
VAET Index
The VAET index contains all and only datoms with :db/valueType
attributes whose value is :db.type/ref
. This is also known as the
reverse index, since it allows efficient navigation of relationships
in reverse. This is similar to graph-style access.
If The Beatles are entity 100, you can see in the following table how their releases would be grouped together in this index.
Datomic's EAVT and VAET indexes can automatically navigate entity relationships in both directions, so you do not need to (and should not) create two attributes that model the same relationship but from different directions.
Datoms API
The datoms API lets you specify a Datomic index, plus a vector of
values in the same order as the index. The example excerpted below searches the
:avet
index for datoms whose a
component is :inv/sku
(->> (d/datoms db {:index :avet :components [:inv/sku]}) (take 3) (map :v))
=> ("SKU-0" "SKU-1" "SKU-10")
Index-range API
The index-range API lets you specify an attribute, and returns all datoms sorted by that attribute, optionally limited by start and end values. The example excerpted below returns all the SKUs between "SKU-42" inclusive and "SKU-44" exclusive.
(->> (d/index-range db {:attrid :inv/sku :start "SKU-42" :end "SKU-44"}) (map :v))
=> ("SKU-42" "SKU-43")