Package io.permazen.index
Indexes provide fast lookup of objects based on field value(s). The Index*
interfaces in this package have
generic type parameters that correspond to the field value type(s), plus a final generic type parameter
corresponding to the "target type". For example, an index on field int
getAccountNumber()
of type
User
will be represented by a Index1
<Integer, User>
, and may be viewed
either as a NavigableSet
<
Tuple2
<Integer, User>>
or a NavigableMap
<Integer,
NavigableSet
<User>>
.
Indexes are accessible through the PermazenTransaction
API:
PermazenTransaction.querySimpleIndex()
- Access the index associated with a simple fieldPermazenTransaction.queryListElementIndex()
- Access the composite index associated with a list field that includes corresponding list indicesPermazenTransaction.queryMapValueIndex()
- Access the composite index associated with a map value field that includes corresponding map keysPermazenTransaction.queryCompositeIndex()
- Access a composite index defined on two fieldsPermazenTransaction.queryCompositeIndex()
- Access a composite index defined on three fieldsPermazenTransaction.queryCompositeIndex()
- Access a composite index defined on four fieldsPermazenTransaction.querySchemaIndex()
- Get database objects grouped according to their schema versions
Simple and Composite Indexes
A simple index on a single field value is created by setting indexed="true"
on the
@PermazenField
annotation.
Composite indexes on multiple fields are also supported. These are useful when the target type needs to be sorted
on multiple fields; for simple searching on multiple fields, it suffices to have independent, single-field indexes,
which can be intersected via NavigableSets.intersection()
, etc.
A composite index on two fields String getUsername()
and float getBalance()
of type User
will be represented by a Index2
<String, Float, User>
; a composite index on
three fields of type X
, Y
, and Z
by a Index3
<X, Y, Z, User>
, etc.
A composite index may be viewed as a set of tuples of indexed and target values, or as various mappings from one or more indexed field values to subsequent values.
A composite index may always be viewed as a simpler index on any prefix of its indexed fields; for example, see
Index2.asIndex1()
.
Complex Sub-Fields
Only simple fields may be indexed, but the indexed field can be either a normal object field or a sub-field of
a complex Set
, List
, or Map
field. However,
complex sub-fields may not appear in composite indexes.
For those complex sub-fields that can contain duplicate values (namely, List
element and
Map
value), the associated distinguishing value (respectively, List
index
and Map
key) becomes a new value that is appended to the index.
The resulting index types associated with indexes on complex sub-fields of some object type Foobar
are as follows:
Complex Field | Indexed Sub-Field | Distinguising Value | Distinguising Type | Index Type |
---|---|---|---|---|
Set <E> |
Set element | n/a | n/a | Index1 <E, Foobar> |
List <E> |
List element | List index | Integer |
Index2 <E, Foobar, Integer> |
Map <K, V> |
Map key | n/a | n/a | Index1 <K, Foobar> |
Map <K, V> |
Map value | Map key | K |
Index2 <V, Foobar, K> |
To ignore the distinguishing values, convert the Index2
back into an Index1
via Index2.asIndex1()
.