删除 indexedDB 对象存储中特定索引值的所有记录

Deleting all records in indexedDB object store for a specific index value

对于数组键为 [a,b] 的对象存储,其中 a 也是一个索引,是否有更有效的方法来删除特定值 a 的所有记录比在索引 a 上打开游标并通过游标删除每条记录?

有没有办法只为索引定义键范围,或者只在 a 上定义键范围并让 b 对任何值开放,这样就可以删除该键范围的所有记录?

在这种特殊情况下,a 是一个不包括零的正整数,b 是一个包括零的正整数。无论 b 的值如何,从 [n,0] 到 [n+1,0] 的键范围是否可以保证 return 等于索引 a=n 的所有键?例如,IDBKeyRange.bound( [2,0], [3,0], false, true) 会 return 索引 a=2?

的所有键

上面的键范围适用于我的测试用例,但我想知道如果 b 不是整数时如何处理这种情况,使其成为一种特殊情况。

似乎以下操作不起作用,因为它只会删除 key2 的记录。一般情况下有这样的方法吗?

i = transaction.objectStore( name ).index( 'a' );
i.delete( 2 );

谢谢。

随着我了解更多并查看下面生成所需结果的代码,我不再确定它为何起作用。键是复合 [ topic, note ] 并且 k 仅设置为主题值。所以,n 中的任何键都不应匹配 k,对吗?

我不明白为什么 n.openCursor( k ) return 编辑要处理的任何记录,因为 none 有一个简单的键。 k 是作为记录的键还是索引值?

T = DB_open.base.transaction( ['notes'], 'readwrite' ),
o = T.objectStore( 'notes' ),
k = IDBKeyRange.only( topic_value );
n = T.objectStore( 'notes' ).index( 'topic' );

n.openCursor( k ).onsuccess = ( e ) =>  { /* stepped through cursor */ };

看来我不明白的是,索引的 key 参数不是实际记录的键,而是索引的键,这里是主题值。对于读取操作和游标,效果很好;但是索引上没有删除方法,例如 deleteAll 等同于 getAll.

我想我在几个月前编写游标代码时一定已经理解了这一点,但现在我对在不打开游标的情况下尝试删除特定索引值的一组记录感到困惑。

It appears that what I wasn't understanding is that the key parameter for an index is not the key of the actual record but the key of the index, here the topic value. For read operations and cursors, that works fine; but there is not a delete method on an index, such as a deleteAll equivalent to getAll.

你是对的,key是索引键。而且没有一个命令可以说 "delete every record matching a certain key or key range in an index"。 Here is some discussion about this - 我的解释是,没有很好的理由反对现有的功能,但它是一个非常罕见的用例,它只是作为一个未实现的功能请求坐在那里。

但是如果主键是一个复合键并且复合键中的第一个条目是您要过滤的字段,您可以使用 KeyRange 并将其传递给 IDBObjectStore.delete 之类的你建议:

In this particular case, a is a positive integer excluding zero and b is a positive integer including zero. Would a key range from [n,0] to [n+1,0] be guaranteed to return all keys for equivalent to index a=n regardless of the value of b? For example, IDBKeyRange.bound( [2,0], [3,0], false, true) would return all keys for index a=2?

是的,那行得通。

您也可以尝试一下并亲眼看看:

var range = IDBKeyRange.bound( [2,0], [3,0], false, true);
console.log(range.includes([2, -1])); // false
console.log(range.includes([2, 0])); // true
console.log(range.includes([2, 100])); // true
console.log(range.includes([2, Infinity])); // true
console.log(range.includes([3, 0])); // false

只是为了好玩...您也可以这样定义键范围:

var range = IDBKeyRange.bound( [2,0], [2,""], false, true);

因为数字排在字符串之前。您可以通过多种其他方式来编写相同的内容。这一切都归结为如何在 IndexedDB 规范中进行跨类型比较。一旦拥有数组或多种类型,事情就会变得有趣起来。