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]);
结论
我提出了两种可选方法,它们都可以有效地解决您的问题。第一个选项是添加一个简单的子 ID 数组和使用 MultiEntry 索引的索引,另一个选项是将子项放在单独的表中。如果您选择第二个选项,您还可以通过使用 dexie-relationships 插件来查询包含父母的孩子或包含孩子的父母。
注意
我将 parentId 索引到子级的原因是,在关系模式中这样做是一种很好的做法,以便能够查询所有子级以查找某个父级(此处未举例说明)。