在Dexie表中搜索数组中的键

时间:2019-07-22 22:27:39

标签: indexeddb dexie

如果我在indexedDB / Dexie表中有以下记录:

{
  id: 1,
  name: "foo",
  children: [{id: 12, bar: "b"},
             {id: 14, bar: "c"}]
}

每个孩子的ID都是唯一的。也就是说,只有1条记录将有一个给定ID为14的孩子。

  1. 如何为孩子建立索引,以便我搜索包含ID为14的孩子的记录?
  2. 然后我如何最有效地搜索包含带有anyOf([3, 7, 9])中的键的孩子的多个记录

3 个答案:

答案 0 :(得分:2)

IndexedDB允许MultiEntry索引,但只能在简单数组上,而不能在对象数组上。但是您可以通过以下方法解决此问题:在侧面保留一个包含所有包含的ID的数组,并对该属性进行索引:

{
  id: 1,
  name: "foo",
  children: [{id: 12, bar: "b"},
             {id: 14, bar: "c"}],
  childrenIds: [12, 14]
}
// Dexie schema:
const db = new Dexie("db");
db.version(1).stores({
  table: "++id, *childrenIds"
});

MultiEntry索引适用于Chromium,Firefox和Safari。 IE11不支持它,但是即将推出的基于Chromium的Edge浏览器将支持。

替代方法

另一种方法是以关系方式设计表:

const db = new Dexie("relDB");
db.version(1).stores({
  parents: "++id",
  children: "++id, parentId"
});

父对象:

{
  id: 1,
  name: "foo",
}

子对象:

{id: 12, bar: "b", parentId: 1}
{id: 14, bar: "c", parentId: 1}

然后,要基于一组子代ID [12、14]来检索父代,请在子代表上使用anyOf()查询:

const children = await db.children.where('id').anyOf([12, 14]).toArray();
const parentIds = new Set(children.map(child => child.parentId));
const parents = await db.parents.bulkGet([...parentIds]);

结论

我提出了两种可选的方法,它们都是有效的解决方案,可以解决您的问题。第一个选项是使用MultiEntry索引添加一个简单的子ID和索引数组,另一个选项是将这些子ID放在单独的表中。如果您选择第二种方法,则使用dexie-relationships插件查询包含父母的孩子或包含父母的孩子可能对您有所帮助。

注意

我之所以在孩子上索引parentId是因为在关系模式中这样做是一种好习惯,以便能够向所有孩子查询某个父级(此处未作说明)。

答案 1 :(得分:0)

它看起来像:

  1. 在多条目索引中只能使用Indexable Types
  2. Edge仍然不支持多条目密钥的indexed-db标准!!!坦率的荒谬。
  3. 允许原始问题has been suggested中描述的行为

答案 2 :(得分:0)

请考虑将父数据冗余地存储在子对象中。例如。表格中的对象看起来像:

{
  "parent" : {
    "id": 1,
    "name": "foo",
  },
  "id": 12,
  "bar": "a"
}

然后您可以在id上创建一个多条目索引。

但是,您无法进行IN样式查询。因为IN本质上是id = 1 or id = 2 or id = 3的简写,#include <iostream> class A{ public : virtual void foo() = 0; }; class B: public A{ public : void foo(){ std::cout << "foo" << std::endl;} }; class C: public A{ void bar(); }; int main() { //C temp; The compiler will complain only if this is initialized without // implementing foo in the derived class C return 0; } 是一个联合,您不能在indexedDB中执行。至少没有效率。在这种情况下,您需要做的是创建3个查询,每个查询一个,针对同一个多条目索引的每个查询,然后将结果合并到一个数组中。