2016-11-17 29 views
3

我在考虑如何使我的项目中的某个操作更加高效。当前实现中的操作从对象存储中加载所有对象,遍历数组并检测对象是否缺少属性,或者该属性是否未定义,如何在第二个数组中收集这些对象的集合,然后删除所有对象这些对象。从索引数据库对象存储中删除缺少属性的对象的有效方法

我已经使用getAll,因为它明显的优于光标迭代。

我同时调用个别删除请求,因此没有加速,但是indexedDB api不断发展以支持对非缺省值的非索引非关键路径进行批量删除。

问题是,如果没有将每个对象完全加载到内存中,则属性不在对象存储库的keypath中时,我无法检查该属性。在某些情况下,这些物体相当大。有时候每个对象的属性都非常大(基本上是一个html文档的字符串)。

我无法使用索引,因为不存在于对象中的属性或没有值的属性不会出现在索引中。

有没有办法避免将这些对象加载到内存中?

我曾考虑过分区,并使用两个对象存储库,一个用于可查询的道具和一个用于完整的数据。但是这会导致每次阅读都需要额外的请求。我的应用程序做了更多的阅读,然后偶尔批量删除操作。

我曾经想过为每个对象存储一个额外的属性,它总是有一个像myObject.doesOtherPropertyHaveValue那样的值,它包含0/1,因此是可索引的,但这看起来也不是很好。当然,我可以通过这个索引查询并使用getAllKeys,并解决了这个问题。但是,现在每个添加/放置都必须保持这种功能依赖性。

任何意见表示赞赏。

回答

2

如果记录的格式为{key, prop},其中prop可能不存在,您可以在[key, prop]上创建索引。当道具存在时,这只会有索引记录。然后打开两个只有键的游标:一个在商店(C1)和一个在索引(C2)上。检查C1.primaryKey是否等于C2.primaryKey [0]。如果是这样,道具是存在的,都推进。如果密钥是而不是相等,则C1指向没有支柱的记录;删除它并推进C1。重复。 (当你击中范围的末端时,注意边缘情况。)

有两个问题:(1)你仍在使用游标,所以仍然支付往返的费用(与getAll()不同);(2)如果prop很大(即HTML文档的主体为你提到),那么即使只是使用键盘游标,你仍然在洗牌大量的数据。

(在未来,我们希望通过增加来解决这个无论是more general query mechanismcustom indexing可能与delete-on-index组合 - 无论是足以令这更简单,更高效)

...收集集第二阵列这样的对象,然后除去所有这些对象的...

如果你坚持这种方法,记住,你可以发出delete()电话,你找他们;不需要收集所有对象,也不需要等待删除完成;您可以使用IDB以“即忘即忘”的方式进行写入操作。

+0

谢谢乔希。我想删除索引的东西,因为我基本上希望'DELETE FROM objectStore WHERE prop not in obj or obj.prop = null or obj.prop = undefined;'数据甚至没有加载到js中。我在火和忘记方面的一个问题是,我非常喜欢'await Promise.all(deleteRequestPromises)'''over'Promise.all(删除).catch()''的语法。当然,如果我删除了索引,我不会需要这个,但我只是想补充一点,说明它现在的工作方式。 – Josh

1

您在正确的道路上反规范化可能是提高性能所必需的。从indexedDB文档中,不可能不幸地查询您需要的方式。

如果真正的瓶颈是I/O或将数据封送到JS-land,那么可能试着在写入数据之前压缩数据,然后在实际需要使用它进行解压缩时解压缩数据? GZIP可以很好地压缩文本,有时减少70%。有对JS一些GZIP库可以工作:

https://github.com/nodeca/pako

但是,一如既往,标杆!

相关问题