Indexeddb search multi values on same index

2.4k views Asked by At

I record a JSON stream in a IndexedDB database and I can not do a search of equality with several values ​​on the same index.

My Datas :

datas = [
  {name : 'Test P1', location : 'P1'},
  {name : 'Test P1', location : 'P1'},
  {name : 'Test P2', location : 'P2'},
  {name : 'Test P2', location : 'P2'},
  {name : 'Test P3', location : 'P3'},
  {name : 'Test P3', location : 'P3'},
  {name : 'Test P3', location : 'P3'}
]

Database construction and request :

// In onupgradeneeded
var objectStore = db.createObjectStore('entreprises', {keyPath: 'id_loc'});
objectStore.createIndex("name", "name");
objectStore.createIndex("location", "location");


//In query section
var transaction = db.transaction('entreprises','readonly');
var store = transaction.objectStore('entreprises');
var index = store.index('location');
// I want select only records where location = P1 and location = P2
var request = index.openCursor(IDBKeyRange.only(['P1', 'P2']));
// Select the first matching record
var request = index.get(IDBKeyRange.only(['P1', 'P2']));

The query finds me any records. Is it possible to do that? Thank you .

3

There are 3 answers

2
hagrawal7777 On

I doubt if you can use an array with only(), API also doesn't say so, check below for IDBKeyRange.only().
Probably that's the reason it is not working for you.

The only() method of the IDBKeyRange interface creates a new key range containing a single value.

So, what you can do is open a cursor for "P1" or "P2" (whichever has lesser number of rows), and then loop through cursor to check if it contains other required value. Below is a sample I created for your handy reference, so adjust it for changes like removing hard-coded values like "location", "P1", "P2" etc.

var resultArr = [];
var keyRange = IDBKeyRange.only("P1");
cursorHandler = indexHandler.openCursor(keyRange);

cursorHandler.onerror = function(event) {
    if (errorCallBack && typeof(errorCallBack) == 'function') {
        errorCallBack(event);
    }
};

cursorHandler.onsuccess = function(event) {
    var cursor = event.target.result;
    if (cursor) {
        if(cursor.value != null && cursor.value != undefined){
            if(cursor.value["location"] == "P2"){
                resultArr.push(cursor.value);
            }
         }
        cursor["continue"]();
    } else{
        var resultObj = {"rows" : resultArr};
        if (successCallBack && typeof(successCallBack) == 'function') {
            successCallBack(resultObj);
        }
    }
    return;
};
6
Josh On

Maybe try something like this:

// ...
objectStore.createIndex('locIndex',['loc1','loc2']);`
// ...
var index = store.index('locIndex');
var request = index.openCursor(IDBKeyRange.only(['P1', 'P2']));
4
Kyaw Tun On

Use multi-query technique by creating cursor for each query

index.get(IDBKeyRange.only('P1')).onsuccess = cursorHandler;
index.get(IDBKeyRange.only('P2')).onsuccess = cursorHandler;

cursorHandler should store the results in sorted array by primary key.