在 Dexie 表中搜索数组中的键

Bre*_*ent 0 indexeddb dexie

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

{
  id: 1,
  name: "foo",
  children: [{id: 12, bar: "b"},
             {id: 14, bar: "c"}]
}
Run Code Online (Sandbox Code Playgroud)

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

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

Dav*_*der 6

IndexedDB 允许多条目索引,但仅限于简单数组,而不是对象数组。但是您可以通过在侧面维护一个包含所有包含的 id 的数组并对该属性建立索引来解决此问题:

{
  id: 1,
  name: "foo",
  children: [{id: 12, bar: "b"},
             {id: 14, bar: "c"}],
  childrenIds: [12, 14]
}
Run Code Online (Sandbox Code Playgroud)
{
  id: 1,
  name: "foo",
  children: [{id: 12, bar: "b"},
             {id: 14, bar: "c"}],
  childrenIds: [12, 14]
}
Run Code Online (Sandbox Code Playgroud)

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

替代方法

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

// Dexie schema:
const db = new Dexie("db");
db.version(1).stores({
  table: "++id, *childrenIds"
});
Run Code Online (Sandbox Code Playgroud)

父对象:

{
  id: 1,
  name: "foo",
}
Run Code Online (Sandbox Code Playgroud)

子对象:

{id: 12, bar: "b", parentId: 1}
{id: 14, bar: "c", parentId: 1}
Run Code Online (Sandbox Code Playgroud)

然后,要根据一组子 id [12, 14] 检索父项,请在子表上使用 anyOf() 查询:

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

结论

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

笔记

我对子项建立索引的原因parentId是,在关系模式中这样做是一个很好的做法,以便能够查询某个父项的所有子项(此处未举例说明)。