【问题标题】:Dexie: How to get all values of a MultiEntry Index?Dexie:如何获取 MultiEntry Index 的所有值?
【发布时间】:2020-08-04 16:32:06
【问题描述】:

我有这些对象,每个对象都有一个“标签”数组:

bookmarks: [
    { url: '...', tags: ['news', 'fun', 'programming'] },
    { url: '...', tags: ['news'] },
    { url: '...', tags: ['fun', 'cooking'] },
    { url: '...', tags: ['hobby', 'fun'] }
]

数据库:

const db = new Dexie("bookmarksdb");
db.version(1).stores({
  bookmarks: 'url, *tags'
});

接收包含所有标签的数组(或集合)的最佳(和最高性能)方式是什么:

['news', 'fun', 'programming', 'cooking', 'hobby']

(有没有办法获取“标签”索引本身的所有值?)

编辑:要显示带有数字的“标签云”,我需要从书签表中读取所有标签。所以,我不需要书签对象本身,只需要它们的“标签”数组。

【问题讨论】:

    标签: database dexie


    【解决方案1】:

    我建议使用索引过滤掉所有包含至少一个标签的书签,然后手动过滤掉:

    const tagsToRequire = ['news', 'fun', 'programming', 'cooking', 'hobby'];
    const bookmarksWithFirstTag = await db.bookmarks
      .where({tags: tagsToRequire[0]})
      .toArray();
    const bookmarkWithAllTags = bookmarkWithFirstTag.filter(bookmark => tagsToRequire.every(tag => bookmark.tags.includes(tag));
    

    您也可以将索引用于所有标签,但不确定您是否会获得更好的性能,因为它需要更多数量的数据库请求。另一方面,在第一个索引非常常用且对象很大的情况下,第二个示例可能会在性能上做得更好:

    const tagsToRequire = ['news', 'fun', 'programming', 'cooking', 'hobby'];
    const keys = await Promise.all(tagsToRequire.map(tag =>
      db.bookmarks.where({tags: tag}).primaryKeys()));
    const intersectedKeys = keys.reduce((prev, curr) => prev.filter(key => curr.includes(key)));
    const bookmarkWithAllTags = await db.bookmark.bulkGet(intersectedKeys); 
    

    第二个示例还需要具有 bulkGet() 操作的 Dexie 版本 3.x。

    【讨论】:

    • 对于“标签云”,我需要所有书签中的所有标签(带有数字),您已经回答了here。这实际上回答了我的第二个(更复杂的)要求:用户将能够从标签云中选择(切换)多个标签,然后应返回并显示所有带有选定标签的书签。非常感谢您的快速回复!
    猜你喜欢
    • 2020-11-30
    • 2021-04-01
    • 2018-02-24
    • 2020-02-06
    • 1970-01-01
    • 2012-10-18
    • 1970-01-01
    • 2020-01-18
    • 2021-01-23
    相关资源
    最近更新 更多