IndexedDB - 具有任意键列表的简单索引上的 IDBKeyRange

IndexedDB - IDBKeyRange on simple index with arbitrary key list

我在 IDB 中有一个对象存储,它在字段 X 上有一个简单(非复合)索引。该索引不是唯一的(许多项目可能具有相同的 X 值)。

我想查询 IDB return X 值为 "foo"、"bar" 或 "bat" 的所有项目。

根据文档,索引 getAll 采用键(在我的例子中是字符串)或 IDBKeyRange。但是,如何使用任意一组键构造 IDBKeyRange,并根据这些键获得所有结果的并集,对我来说并不明显。

您不能在单个请求中执行此操作。 indexedDB 当前不支持 "OR" 样式查询。

另一种解决方案是对每个值执行一个请求。基本上,对于每个值,在值的索引上使用 getAll,然后将所有数组连接成一个数组(可能合并重复项)。由于您使用的是 getAll,因此您实际上并没有那么多针对数据库的往返行程。在设置这个索引时,你基本上想要一个存储 "things",其中每个 "thing" 都有一个 属性,例如 "tags",其中 tags 是值的数组(每个都是一个字符串)。您在 "tags" 属性 上创建的索引应标记为多条目索引。

当然,也有创造性的 hacky 解决方案。这是一个。请记住,如果您拥有具有不同标签集的事物但您仍想匹配共享的事物,这将完全无用,这仅在您不关心任何事物是否具有额外标签时才有效。例如,考虑每组不同的值,忽略顺序。我们称它们为组。例如。 foo 是 1,bar 是 2,bat 是 3,foo-bar 是 4,foo-bat 是 5,bar-bat 是 6,等等。你可以给每组一个键,就像我刚刚在例子。然后您可以将组密钥存储为对象中的 属性 。每次去存储对象时,计算它的组键。您可以预先计算所有组键,或开发一个散列式函数,在给定一组任意字符串值的情况下生成特定键。当然,您在存储时和构建请求查询时需要多支付一点前期费用,但您可以节省大量处理,因为 indexedDB 会在之后进行所有处理。所以你想要一个简单的快速散列。当然,这增加了复杂性。但也许它会奏效。只需找到一个简单的 JS 哈希即可。修改它,以便在使用之前按字典顺序存储设置的值(这样值顺序的差异不会导致哈希值的差异)。因此,更具体地解释一下,对于事物对象存储,每个事物对象都有一个名为"tags-hash" 的属性。您在此创建一个基本索引(不是唯一的,不是多条目的)。每次你在商店里放一个东西,你计算标签哈希的值,并在调用 put 之前设置 属性 的值。然后,每次你想查询时,你计算你想查询的标签数组的散列,然后调用 getAll(calculated-hash-value),它会给你所有具有这些确切标签的东西。