Compound Index
A compound (or composite) index is an index based on several keypaths. It can be used to efficiently index multiple properties in one index to easily find the existance of the combination of two keys and their values.
In Dexie, a compound index must be specified when defining the schema:
In the above sample, records containing valid keys in the firstName and lastName properties will be indexed. If having stored an object with properties {firstName: 'foo', lastName: 'bar'}
, it can be efficiently looked up using:
...which can also be expressed as:
The latter version is a special case that only works in Dexie >=2.0 and that can match by multiple properties, no matter whether your browser supports compound queries or not.
Sample
How Compound Index Works
A compound index can be viewed as the index of a concatenation of two properties. They are expressed as "[prop1+prop2]" both when declaring them and when referring to them in where()-clauses. But when expecting a compound value, an array is expected, as compound keys are represented by arrays in IndexedDB.
Matching First Part Only
To find all friends with firstName='foo'
but has an arbitrary lastName, we actually do not need to use a normal index - a compound index who's first part is 'firstName' can also perform this query. For the compound index '[firstName+lastName]', the query should be expressed as follows:
From Dexie 3.x, compound indexes also adds virtual indexes (without actually adding them to indexedDB) acting as a representation for partial parts of the index so you can do the following query:
Note that only the leading parts of a compound index can be used alone - never the trailing parts. This is the same rule for any BTree database with compisite index support. You cannot use the compound index [firstName+lastName] to search for lastName only, but you can use it to search firstName only.
Virtual indexes have the full support for any operation, just like ordinary indexes, such as equalsIgnoreCase(), anyOf(), etc.
Matching Multiple Values
To find specific people using both their first and last name, we can use WhereClause.anyOf(). This allows us to have multiple criteria for the properties that are part of the compound index. The syntax should be as follows:
This will yield both "Foo Bar" and "Baz Qux".
Compound Primary Key
A primary key can also be compound in the same manner as indexes. However, a compound primary key cannot be auto-incremented since it is a combined array of multiple properties.
The above sample uses a compound primary key containing two properties: firstName and lastName.
Compound Type is Array
Compound keys are represented by arrays of the contained properties. This means that in methods where a key is expected, you should provide an array key:
Browser limitations
Internet Explorer, non-chromium Edge and Safari < v10 does not support compound indexes or compound primary keys. You can declare compound indexes, but you'd get an error when trying to use them in a plain where('[x+y]') manner. But if passing an object to Table.where() (as samplified multiple times on this page), the query will work on all browsers and only utilize the compound index if browser supports it, otherwise fallback to using a simple index, or even just a full table scan to filter it out:
Dexie will find out whether it can utilize the compound index or not. If user is on IE/old Edge/old safari, it will still perform the query without utilizing compound index (just not as performant).
Using with orderBy()
If an index is compound using "[firstName+lastName]", Table.orderBy() will sort the contents based on firstName first and lastname secondary. Reverse the order of the compound entries to sort by lastName first. The sorting does not only apply when using "orderBy()" but also when using a WhereClause targeting the compound index, such as:
The above query will list all people who has a lastName starting with letter 'A'. Result will be sorted by lastName first and firstName secondly when people have the same lastName but different firstName. Notice that you cannot use that compound key to sort by firstName first. Must add another index with a reversed order of the properties to accomplish that. Notice also that if any person lacks either of the properties, it will not be contained in the result. Compound indexes will only index objects that has valid keys for all contained keypaths.
Multiple Combinations
If your app needs to support several ways of sorting, you can add several combinations of the same properties, thus adding several indexes based on different combinations of the order of your properties.