Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Multi index querying doesn't seem to be supported. #85

Open
joegaudet opened this issue Mar 22, 2020 · 7 comments
Open

Multi index querying doesn't seem to be supported. #85

joegaudet opened this issue Mar 22, 2020 · 7 comments

Comments

@joegaudet
Copy link

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:

Screen Shot 2020-03-22 at 12 35 17 PM

However, the store does not return anything:

const r = await this.store.query('restaurant', {areas: ["1"]});
// r === []

What am I missing.

@joegaudet
Copy link
Author

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

@mydea
Copy link
Owner

mydea commented Mar 23, 2020

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!

@joegaudet
Copy link
Author

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.

@joegaudet
Copy link
Author

This stuff here:

https://github.com/mydea/ember-indexeddb/blob/master/addon/services/indexed-db.js#L610

Not intended for multi indexes?

@joegaudet
Copy link
Author

joegaudet commented Mar 23, 2020

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?

@joegaudet
Copy link
Author

Opened a PR for initial comment.

@joegaudet
Copy link
Author

Will think about how to test.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants