从索引数据库存储中删除缺少属性

时间:2016-11-17 18:05:41

标签: javascript indexeddb

我正在考虑如何在我的项目中进行某项操作更有效率。当前实现中的操作从对象存储加载所有对象,遍历数组并测试对象是否缺少属性,或者属性是否未定义,在第二个数组中收集这些对象的集合,然后删除所有对象这些对象。

我已经在使用getAll,因为它在游标迭代方面具有明显的性能优势。

我同时调用单个删除请求,因此没有加速但是indexedDB api不断发展以支持对缺少值的非索引非keypath道具进行批量删除。

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

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

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

我考虑过分区,并使用两个对象存储库,一个用于可查询道具,一个用于完整数据。但随后这就变成了每次读取都要做额外的请求。我的应用程序执行了更多阅读,然后偶尔进行批量删除操作。

我已经考虑过为每个对象存储一个额外的属性,该属性总是具有包含0/1的myObject.doesOtherPropertyHaveValue值,因此是可索引的,但这似乎也不是很好。当然我可以通过这个索引查询并使用getAllKeys并解决问题。但是,现在每个add / put都必须保持这种功能依赖性。

感谢任何建议。

2 个答案:

答案 0 :(得分:2)

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

这有两个问题:(1)你还在使用游标,所以仍然支付往返费用(不像getAll()),以及(2)如果支柱很大(即你提到的一个HTML文档)然后即使只是使用关键游标,你仍然在改变大量的数据。

(将来我们希望通过添加more general query mechanismcustom indexing可能与delete-on-index相结合来解决这个问题 - 其中任何一个都可以使这更容易和更多有效)的

  

...在第二个数组中收集这些对象的集合,然后删除所有这些对象......

如果您坚持使用此方法,请记住您可以在找到它们时发出delete()个电话;不需要收集所有对象,也不需要等待删除完成;你可以在火灾中使用IDB并忘记"写作业的时尚。

答案 1 :(得分:1)

您正走在正确的道路上,可能需要非规范化来提高性能。从indexedDB文档中,无法查询您需要的方式。

如果真正的瓶颈是I / O或将数据编组到JS-land中,那么可能在写入之前尝试压缩数据并在实际需要对其执行某些操作时解压缩? GZIP可以很好地压缩文本,有时可以减少70%。有一些适用于JS的GZIP库可以工作:

https://github.com/nodeca/pako

但是,一如既往,基准!