IndexedDB搜索密钥和排序

时间:2016-09-26 14:59:10

标签: javascript indexeddb

目前我有2个功能。一个用于查询数据库以查找具有特定键/值对的结果,另一个用于按特定键排序的getAll行。 有没有办法结合这两个?所以我希望有一个函数,你可以在商店中搜索a = 1,按b asc排序的对象。

按索引获取结果的功能:

getByIndex : function(store,indexKey,indexValue,callback){
    var results = [];
    this._initTransaction(store,"readonly",function(err,transaction){

        var index = transaction.objectStore(store).index(indexKey);
        index.openCursor(IDBKeyRange.only(indexValue)).onsuccess = function(event) {
          var cursor = event.target.result;
          if (cursor) {
            results.push(cursor.value);
            cursor.continue();
          } else {
            callback(true,results);
          }
        };
    })  
}

获取按键排序的结果的函数:

getSorted : function(store,sortKey,callback){
    var results = [];
    this._initTransaction(store,"readonly",function(err,transaction){

        var index = transaction.objectStore(store).index(sortKey);
        index.openCursor(null,'next').onsuccess = function(event) {
            var cursor = event.target.result;
          if (cursor) {
            results.push(cursor.value);
            cursor.continue();
          } else {
            callback(true,results);
          }
        };
    })      
},

感谢您的帮助!

1 个答案:

答案 0 :(得分:0)

在两个属性上创建索引:

function myOnUpgradeNeeded(event) {
  // ...
  var index = store.createIndex('myIndex', ['a', 'b']);
}

定义一个函数,在索引上打开一个有界游标并迭代:

function query(db, a, callback) {
  if(!a) {
    throw new TypeError('this only works if a is defined');
  }

  var results = [];
  var tx = db.transaction('store');
  tx.oncomplete = function(event) {
    callback(results);
  };
  var store = tx.objectStore('store');
  var index = store.index('myIndex');

  var lowerBound = [a];

  // How you define the upper bound depends on the type. This assumes 
  // that a is a number. For example, if a is a string, you need to 
  // use a different boundary definition. See the gist by Mr. Bell 
  // below for an example of how to create other types of bounds. You 
  // simply need to determine whatever is the 'next' value that would 
  // come after `a`s value in your data.
  var upperBound = [a+1];

  var range = IDBKeyRange.bound(lowerBound, upperBound, false, true);
  var request = index.openCursor(range);
  request.onsuccess = function(event) {
    var cursor = event.target.result;
    if(cursor) {
      results.push(cursor.value);
      cursor.continue();
    }
  };
}

然后叫它:

var request = indexedDB.open(...);
request.onsuccess = function(event) {
  var db = event.target.result;
  query(db, 1, function(results) {
    // ...
  });
};

这比较了不同长度的数组键路径,因此即使索引在[a,b]上定义,该范围也仅比较[a] ... [a + 1]。比较不同长度的数组键路径是完全可以的,比较只比较较短数组的长度值。

索引中条目的顺序是每[a,b]。因此,如果您将索引条目限制为包含a的索引条目,那么您将获得由b排序的子集,其中每个a都是目标a,这是我理解的目标。