2.6. Index

It is sometimes useful to retrieve records in an object store through other means than their key. An index allows looking up records in an object store using properties of the values in the object stores records.

An index is a specialized persistent key-value storage and has a referenced object store. The index has a list of records which hold the data stored in the index. The records in an index are automatically populated whenever records in the referenced object store are inserted, updated or deleted. There can be several indexes referencing the same object store, in which changes to the object store cause all such indexes to get updated.

The values in the index’s records are always values of keys in the index’s referenced object store. The keys are derived from the referenced object store’s values using a key path. If a given record with key X in the object store referenced by the index has the value A, and evaluating the index’s key path on A yields the result Y, then the index will contain a record with key Y and value X.

For example, if an index’s referenced object store contains a record with the key 123 and the value { name: "Alice", title: "CEO" }, and the index’s key path is “name“ then the index would contain a record with the key “Alice“ and the value 123.

Records in an index are said to have a referenced value. This is the value of the record in the index’s referenced object store which has a key equal to the index’s record’s value. So in the example above, the record in the index whose key is Y and value is X has a referenced value of A.

In the preceding example, the record in the index with key “Alice“ and value 123 would have a referenced value of { name: "Alice", title: "CEO" }.

Each record in an index references one and only one record in the index’s referenced object store. However there can be multiple records in an index which reference the same record in the object store. And there can also be no records in an index which reference a given record in an object store.

The records in an index are always sorted according to the record‘s key. However unlike object stores, a given index can contain multiple records with the same key. Such records are additionally sorted according to the index‘s record‘s value (meaning the key of the record in the referenced object store).

An index has a name, which is a name. At any one time, the name is unique within index’s referenced object store.

An index has a unique flag. When this flag is set, the index enforces that no two records in the index has the same key. If a record in the index’s referenced object store is attempted to be inserted or modified such that evaluating the index’s key path on the records new value yields a result which already exists in the index, then the attempted modification to the object store fails.

An index has a multiEntry flag. This flag affects how the index behaves when the result of evaluating the index’s key path yields an array key. If the multiEntry flag is unset, then a single record whose key is an array key is added to the index. If the multiEntry flag is true, then the one record is added to the index for each of the subkeys.

2.6.1. Index Handle

Script does not interact with indexes directly. Instead, within a transaction, script has indirect access via an index handle.

An index handle has an associated index and an associated object store handle. The transaction of an index handle is the transaction of its associated object store handle. Multiple handles may be associated with the same index in different transactions, but there must be only one index handle associated with a particular index within a transaction.

An index handle has a name, which is initialized to the name of the associated index when the index handle is created. The name will remain constant except when an upgrade transaction is running.