ember-indexeddb
ember-indexeddb copied to clipboard
Multi index querying doesn't seem to be supported.
Setup like so:
export default IndexedDbConfigurationService.extend({
currentVersion: 1,
version1: computed(function () {
return {
stores: {
'restaurant': '&id,*areas'
}
};
}),
mapTable: computed(function () {
return {
'restaurant': (item) => ({
id: item.id,
json: this._cleanObject(item),
areas: get(item, 'relationships.areas.data').map(_ => _.id)
})
}
})
});
Can see that the db is loaded as expected:

However, the store does not return anything:
const r = await this.store.query('restaurant', {areas: ["1"]});
// r === []
What am I missing.
This here seems to be the issue:
https://github.com/mydea/ember-indexeddb/blob/master/addon/services/indexed-db.js#L567
should have a predicate index.multi
Hmm, the line you quoted is about Compound Index, but I believe you are talking about MultiEntry Index.
I have not added any special support for MultiEntry indices so far. However, looking through the Dexie docs, it appears you should be able to solve this specific usecase by simply querying for {areas: "1"}. Basically, you can, as of now, only query for a single item in the array (= includes).
To be able to have and behavior natively, we'd need to add something like this here (multi index does not work together with compound index):
https://github.com/mydea/ember-indexeddb/blob/master/addon/services/indexed-db.js#L548
if (keys.length === 1) {
let key = keys[0];
if (typeOf(query[key]) === 'array') {
let values = query[key];
let result = db[type].where(key).equals(values.shift());
while(values.length > 0) {
result.and(key).equals(values.shift());
}
return result.distinct();
}
return db[type].where(key).equals(query[key]);
}
That seems like it should work, but I've just written that from the top of my head. I'd love to accept a PR with that change, ideally tested - if you want to tackle that, I'd love to guide you if necessary!
Hmm, I was thinking it more like an SQL in a statement like so:
select * from foo where id in (1,2,3)
So it's more like an or.
This stuff here:
https://github.com/mydea/ember-indexeddb/blob/master/addon/services/indexed-db.js#L610
Not intended for multi indexes?
Taking an approach like this so far:
// Else, filter manually
return Object.entries(query)
.reduce(
(query, [queryKey, queryValue]) => {
let index = indexMap[queryKey];
let isMulti = index.multi && isArray(queryValue);
if (!query) {
return isMulti
? db[type].where(queryKey).anyOf(...queryValue)
: db[type].where(queryKey).equals(queryValue);
} else {
let predicate = isMulti
? (item) => get(item, queryKey).any(_ => queryValue.includes(_))
: (item) => get(item, queryKey) === queryValue;
return query.and(predicate);
}
}, null);
Seems to be working, curious, have you had any success with relationships between objects? Do they need to be async false?
Opened a PR for initial comment.
Will think about how to test.