使用较短数组查询IndexedDB复合索引

izkcnapc  于 2023-01-15  发布在  IndexedDB
关注(0)|答案(3)|浏览(314)

IndexedDB允许你在多个属性上建立索引,就像你有{a: 0, b: 0}这样的对象,你可以在ab上建立索引。
复合索引的行为是pretty weird,但显然它应该可以使用比复合索引短的数组进行查询,所以在我的示例中,我应该能够查询[0]之类的对象,并获得a==0的结果。
但我似乎不能让它工作。这里有一个you can run on JS Bin的例子:

var db;

request = indexedDB.open("test", 1);
request.onerror = function (event) { console.log(event); };

request.onupgradeneeded = function (event) {
  var db = event.target.result;
  db.onerror = function (event) { console.log(event); };

  var store = db.createObjectStore("store", {keyPath: "id", autoIncrement: true});
  store.createIndex("a, b", ["a", "b"], {unique: true});

  store.add({a: 0, b: 0});
  store.add({a: 0, b: 1});
  store.add({a: 1, b: 0});
  store.add({a: 1, b: 1});
};

request.onsuccess = function (event) {
  db = request.result;
  db.onerror = function (event) { console.log(event); };

  console.log("Only [0, 0]");
  db.transaction("store").objectStore("store").index("a, b").openCursor(IDBKeyRange.only([0, 0])).onsuccess = function (event) {
    var cursor = event.target.result;
    if (cursor) {
      console.log(cursor.value);
      cursor.continue();
    } else {
      console.log("Any [0, x]");
      db.transaction("store").objectStore("store").index("a, b").openCursor(IDBKeyRange.only([0])).onsuccess = function (event) {
        var cursor = event.target.result;
        if (cursor) {
          console.log(cursor.value);
          cursor.continue();
        }
      };
    }
  };
};

Here is the JS Bin link again.
我看到的输出是:

Only [0, 0]
Object {a: 0, b: 0, id: 1}
Any [0, x]

但我希望看到:

Only [0, 0]
Object {a: 0, b: 0, id: 1}
Any [0, x]
Object {a: 0, b: 0, id: 1}
Object {a: 0, b: 1, id: 2}

我哪里做错了?

zbdgwd5y

zbdgwd5y1#

觉吞回答的一个更一般的版本是:如果已知所有键都是具有两个非数组元素的数组,并且您希望键与[x, <any>]匹配,则使用IDBKeyRange.bound([x], [x, []])

e5nqia27

e5nqia272#

您应该使用密钥范围IDBKeyRange.bound([0], [0, '']),以便包括所有以[0]开头的密钥。

iyfamqjs

iyfamqjs3#

为了解释为什么伊万(和觉)的答案确实有效:可以比较不同类型的值
只有当你确定你在比较numbers时,你才可以使用IDBKeyRange.bound([x], [x, MAX_NUMBER])(如果 b〈MAX_NUMBER)或IDBKeyRange.bound([x], [x, '']),但是在一般情况下(假设没有数组子键),你必须把一个空数组([])作为 b 子键的上限。
来自W3C规范:
数字键小于日期键。日期键小于字符串键。字符串键小于二进制键。二进制键小于数组键

相关问题