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

dum*_*ter 2 javascript indexeddb

IndexedDB 允许您在多个属性上创建索引。就像你有对象一样,{a: 0, b: 0}你可以在a和上创建索引b。

复合索引的行为非常奇怪,但显然应该可以使用比复合索引短的数组进行查询。所以在我的例子中,我应该能够查询类似的东西[0]并获得 a==0 的结果。

但我似乎无法让它发挥作用。这是您可以在 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();
        }
      };
    }
  };
};
Run Code Online (Sandbox Code Playgroud)

这里又是 JS Bin 链接。

我看到的输出是:

Only [0, 0]
Object {a: 0, b: 0, id: 1}
Any [0, x]
Run Code Online (Sandbox Code Playgroud)

但我希望看到:

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}
Run Code Online (Sandbox Code Playgroud)

我哪里错了?

Kya*_*Tun 5

您应该使用 key range IDBKeyRange.bound([0], [0, '']),以便[0]包含所有以开头的键。


Iva*_*van 5

俞觉屯的回答稍微更一般的版本:如果所有的键被称为是与两个非数组元素阵列,以及你想要的那些匹配[x, <any>],使用IDBKeyRange.bound([x], [x, []])。