一种从indexedDB对象存储中删除缺少属性的对象的有效方法
An efficient way of removing objects from an indexedDB object store that are missing a property
我正在思考如何使我的一个项目中的某个操作更有效率。当前实现中的操作从对象存储中加载所有对象,遍历数组并测试对象是否缺少属性或属性是否未定义,在第二个数组中收集这些对象的集合,然后删除所有这些对象。
我已经在使用gettall了,因为它比游标迭代有明显的性能优势。
我同时调用单独的删除请求,所以没有速度,但indexedDB api发展到支持批量删除的非索引的非keypath道具是缺失的值。
问题是,如果不将每个对象完全加载到内存中,当属性不在对象存储的键盘中时,我没有办法检查属性。在某些情况下,对象相当大。有时,每个对象的其中一个属性非常大(本质上是html文档的字符串)。
我不能使用索引,因为对象中不存在的属性,或者没有值的属性,不会出现在索引中。
是否有一种方法可以避免将这样的对象加载到内存中?
我考虑过分区,并使用两个对象存储,一个用于可查询的道具,一个用于完整的数据。但这就意味着每次读取都必须执行额外的请求。我的应用程序做了更多的读取,而不是偶尔的批量删除操作。
我想过为每个对象存储一个额外的属性,它总是有一个像myObject.doesOtherPropertyHaveValue
这样包含0/1的值,因此是可索引的,但这似乎也不太好。当然,我可以通过这个索引查询,并使用getAllKeys,这就解决了问题。但是,现在每个add/put都必须维护这个功能依赖。
如果记录的形式为{key, prop}
,其中prop可能不存在,则可以在[key, prop]
上创建索引。只有当prop存在时,才会有索引记录。然后打开两个仅键游标:一个在存储(C1)上,另一个在索引(C2)上。检查一下C1。primaryKey = C2.primaryKey[0]。如果是,道具存在,推进两者。如果键不相等,则C1指向没有prop的记录;删除它并推进C1。重复。(当您到达范围的末尾时,要注意边缘情况。)
这有两个问题:(1)你仍然使用游标,所以仍然支付往返的成本(不像getAll()
),(2)如果prop很大(即你提到的HTML文档的主体),那么即使只是使用键游标,你仍然在打乱大量的数据。
(将来我们希望通过添加更通用的查询机制或自定义索引(可能与delete-on-index相结合)来解决这个问题,这两种方法都会使这个问题更容易、更有效)
…在第二个数组中收集这些对象的集合,然后删除所有这些对象…
如果你坚持这种方法,记住你可以发出delete()
调用,因为你发现他们;不需要收集所有对象,也不需要等待删除完成;您可以以"即发即弃"的方式使用IDB进行写操作。
您在正确的道路上,非规范化可能是提高性能所必需的。不幸的是,从indexedDB文档中没有办法查询您需要的方式。
如果真正的瓶颈是I/O或将数据编组到JS-land,那么也许可以尝试在写入数据之前压缩数据,并在实际需要对数据进行处理时解压缩数据?GZIP可以很好地压缩文本,有时最多可以压缩70%。有几个GZIP库可以为JS工作:
https://github.com/nodeca/pako但是,一如既往,基准!
- 在不知道深度或父属性的情况下从对象中删除属性
- 解析JSON并从中删除对象会出错
- 如何从对象中删除属性
- 在特定条件下从存储在localStorage中的阵列中删除对象
- Es6:能够在设置/更新/删除对象属性时调用自定义方法
- AngularJS:删除重复的对象并按值对数组进行重新排序
- 正在从对象中删除值
- 正在从列表中删除对象
- 删除对象时终止setInterval
- jQuery-检测选择对象是否添加或删除了选项
- 如何在不删除类似侦听器的情况下从父对象中删除jQuery事件侦听器
- 为什么没有从数组中存在的对象中删除属性
- 从Three.js场景中删除许多对象的速度较慢
- 删除两个独立对象中的属性,而不使用多余的删除语句
- JS:将 EventListener 添加到动态创建的 DOM 对象中,这些对象删除 parentNode
- Java 脚本 json 解析对象:删除操作后不删除“,”
- JavaScript对象删除特定键值中的引号
- tinyMCE对象删除事件触发器
- javascript地图对象删除不工作
- Javascript对象删除元素