[IndexedDB] MultiEntry compound index proposal

Current IndexedDB spec does not allow MultiEntry index for array keyPath
(compound index). Implementation of multiEntry compound index is rather
straight forward, but ambiguous specification is an issue as explained in
this bug report <https://www.w3.org/Bugs/Public/show_bug.cgi?id=21836#c2>.
MultiEntry compound indexes are required for efficient key joining that
involve multiEntry key.

The behaviour of multiEntry attribute if array keyPath index can be defined
by taking into account of multiEntry attribute of constituting indexes.
Each item (string) of an array keyPath index is an index name on the object
store, the index is called constituting index.

Creating array keyPath index with optional multiEntry attribute is allowed
and does not throw Error. When creating array keyPath index with multiEntry
attribute set to true, but none of its constituting indexes exists or none
of its constituting indexes has multiEntry attribute set to true, throw
ConstraintError.

If multiEntry attribute of array keyPath index is false or not exist,
algorithm for storing a record and evaluation of keyPath value is the same
as currently defined, but additionally each item in keyPath sequence can be
an index name, in this case index key are referred by the constituting
index.

If multiEntry attribute of array keyPath index is true, algorithm for
storing a record is modified such that each item in combination of keys of
constituting indexes as its key and key as its value.

As an illustrating example, support we have the following record.

var human = {
  taxon: 9606,
  classification: ['Animalia', 'Mammalia', 'Primates'],
  name: {
    genus: 'Homo',
    species: 'sapiens'
  },
  habitat: ['asia', 'americas', 'africa', 'europe', 'oceania']
}

store = db.createObjectStore('specie', {keyPath: 'taxon'});
store.createIndex('clade', 'classification', {multiEntry: true});
store.createIndex('habitat', 'habitat', {multiEntry: true});
store.createIndex('binomen', ['name.genus', 'name.species']);


The following composite index is used to list specie table.

store.createIndex('specie', ['classification', 'binomen'], {unique:
true, multiEntry: false});

It should create a index value of

[['Animalia', 'Mammalia', 'Primates'], ['Homo', 'sapiens']]

Notice that 'bionomen' is index name, not keyPath of record value.

The following composite index is used to query specific clad order by name.

store.createIndex('clad-name', ['clade', 'binomen'], {multiEntry: false});

It should crate index values of

['Animalia', ['Homo', 'sapiens']]
['Mammalia', ['Homo', 'sapiens']]
['Primates', ['Homo', 'sapiens']]


The following composite index is used to query habitant and clad.

store.createIndex('clad-habitat', ['clade', 'habitat', 'binomen'],
{multiEntry: true});
It should crate index values of
['Animalia', 'africa', ['Homo', 'sapiens']]
['Animalia', 'asia', ['Homo', 'sapiens']]
['Animalia', 'americas', ['Homo', 'sapiens']]
['Animalia', 'europe', ['Homo', 'sapiens']]
['Animalia', 'oceania', ['Homo', 'sapiens']]
['Mammalia', 'africa', ['Homo', 'sapiens']]
['Mammalia', 'asia', ['Homo', 'sapiens']]
['Mammalia', 'americas', ['Homo', 'sapiens']]
['Mammalia', 'europe', ['Homo', 'sapiens']]
['Mammalia', 'oceania', ['Homo', 'sapiens']]
['Mammalia', 'africa', ['Homo', 'sapiens']]
['Primates', 'africa', ['Homo', 'sapiens']]
['Primates', 'asia', ['Homo', 'sapiens']]
['Primates', 'americas', ['Homo', 'sapiens']]
['Primates', 'europe', ['Homo', 'sapiens']]
['Primates', 'oceania', ['Homo', 'sapiens']]

Alternatively, this problem can also be solved by Bug 10000
<https://www.w3.org/Bugs/Public/show_bug.cgi?id=10000> using index key
created by expression. Expression based index is very powerful and can
solve many problems including full-text search index.

However multiEntry compound index is common use case and this proposal
is expected behaviour of such index and should be baked into IndexedDB
API. If web developers, or wrapper library are generating multiEntry
compound index using expression index, handling schema changes will be
nightmare.


Best,

Kyaw

Received on Sunday, 17 November 2013 04:22:19 UTC