繁体   English   中英

从索引数据库存储中删除缺少属性的对象的有效方法

[英]An efficient way of removing objects from an indexedDB object store that are missing a property

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

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

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

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

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

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

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

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

任何建议表示赞赏。

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

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

(将来我们想通过添加更通用的查询机制或可能与index-on-index相结合的自定义索引来解决这个问题 - 其中任何一个都会使这更容易和更有效)

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

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

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

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

https://github.com/nodeca/pako

但是,一如既往,基准!

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM