2016-09-26 2 views
0

В настоящее время у меня есть 2 функции. Один для запроса БД для результатов с определенной парой ключ/значение и один для строк getAll, отсортированных по определенному ключу. Есть ли способ объединить эти два? Поэтому я хочу иметь функцию, в которой вы ищете хранилище для объектов, где a = 1 отсортировано по b asc.IndexedDB поиск ключа и сортировки

Функция, чтобы получить результаты по индексу:

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); 
      } 
     }; 
    })  
}, 

Спасибо за вашу помощь!

ответ

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], r ange сравнивает только [a] ... [a + 1]. Совершенно нормально сравнивать массивные пути ключей разных длин, сравнение сравнивает только значения с длиной более короткого массива.

Порядок записей в индексе соответствует [a, b]. Поэтому, если вы ограничиваете записи индекса теми, которые содержат a, тогда вы получаете подмножество, упорядоченное по b, где каждый a является целью a, и это то, что я понимаю, чтобы быть целью.

+1

Чтобы сделать, где «a = 1 отсортировано по b asc», вам нужен индекс на '['a', 'b']', тогда вы можете открыть курсор на 'IDBKeyRange.bound ([1], [2 ], false, true). Если вы инвертируете индекс (как у вас есть), вы увидите значения с помощью! = 1. Хотите взять удар при обновлении своего ответа? –

+0

Спасибо, Джош, я думаю, я исправил это. У вас еще достаточно очков, чтобы отредактировать ответ? Вы можете, если хотите. – Josh

+1

Все еще не совсем верно: IDBKeyRange.bound ([a], [a]) - это диапазон ключей, содержащий только один возможный ключ - это не префиксный матч. Я буду бросать в +1 –

Смежные вопросы