dexie / Dexie.js

A Minimalistic Wrapper for IndexedDB
https://dexie.org
Apache License 2.0
11.48k stars 642 forks source link

Querying Data from an Array with WhereClause.equals() #871

Closed jwlms closed 5 years ago

jwlms commented 5 years ago

After reading the documentation and starting to write queries with Dexie, I've run into an issue for querying data stored as an Array. I'm not sure if it's a limitation of the library, or my misuse of it.

I'm trying to retrieve records if they match one or more elements I provide in the equals clause, for example I would like to write a query that would retrieve all records that include "Google" as a member of the array.

The table:

Screen Shot 2019-07-15 at 4 48 38 PM

Example query:

db.table_name.where('search_engines').equals(["Google"]).toArray()}).then((data)=> {
// use data
});

This returns records that only have the value of ["Google"]. However, it doesn't return records with more than one item in the Array, (e.g., ["Google", "Bing"]). I would assume that the anyOf method would be useful here, but using this returns no records. Is a query like this possible with Dexie or is it only possible to check that the Array matches exactly?

dfahlander commented 5 years ago

For that, use MultiEntry index.

const db = new Dexie('yourDbName');
db.version(1).stores({
  tableName: '++id, *search_engines'
});

// Add entries:
await db.tableName.bulkAdd([{
  name: "all",
  search_engines: ["Google", "Yahoo", "Bing"]
}, {
  name: "some",
  search_engines: ["Bing"]
}, {
  name: "some-other",
  search_engines: ["Yandex", "Search Encrypt"]
}]);

// Query
const googles = await db.tableName.where({search_engines: "Google"}).toArray();

// Gives googles = [{id: 1, name: "all", search_engines: ["Google", "Yahoo", "bing"]}]
const bings = await db.tableName.where({search_engines: "Bing"}).toArray();
// Gives bings = [{
//    id: 1, name: "all", search_engines: ["Google", "Yahoo", "bing"]
//  }, {
//    id: 2, name: "some", search_engines: ["Bing"]
//  }]

// Starting with "Y":
const yEngines = await db.tableName.where('search_engines').startsWith("Y").toArray();
// Gives yEngines = [{
//    id: 1, name: "all", search_engines: ["Google", "Yahoo", "bing"]
//  }, {
//    id: 3, name: "some-other", search_engines: ["Yandex", "Search Encrypt"]
//  }]
jwlms commented 5 years ago

Thanks for the response and detailed example!

As you pointed out you have already covered this in the docs, but obviously I had some difficulty in discovering it — at any rate it's a pretty killer library.

I ended up putting in a work around for my specific issue, but will revisit to use the MultiEntry.