0

I want to retrieve all those values which matches one of the passed values. This is like IN operator in SQL.

One straight approach is to open a cursor (cursor open on an index) and loop through the values to check if it matches one of them, but it looks in-efficient because it requires reading whole data store.

Another approach could be looping through all the required values and using IDBObjectStore.get() on them but then I am not sure if it can be efficient then above approach.

IDBKeyRange certainly cannot help here because I want IN given values and not some lower and upper bound range.

Any thoughts?

hagrawal7777
  • 14,103
  • 5
  • 40
  • 70

1 Answers1

0

Yes, ideally you have an index on the property and you can open a cursor on the index. But you don't need to iterate over the whole store - just the values you're looking for.

Given a schema like this:

store = db.createObjectStore('records');
store.createIndex('by_field1', 'field1'); // implicitly unique:false

You'd do this:

function findValues(passed, callback) {
  var tx = db.transaction('records');
  var store = tx.objectStore('records');
  var index = store.index('by_field1');

  // accumulate matching records here
  var results = [];

  // asynchronously loop over the passed values
  function nextValue() {
     if (!passed.length) {
       // all done!
       callback(results);
       return;
     }

     // open a cursor matching just the current value we're looking for
     var value = results.shift();
     var request = index.openCursor(IDBKeyRange.only(value));
     request.onsuccess = function() {
       var cursor = request.result;
       if (!cursor) {
         nextValue();
       } else {
         results.push(cursor.value);
         cursor.continue();
       }
     };
  }
  nextValue();
}

This could be made more efficient by opening one cursor for each of the passed values and iterating them all in parallel, accumulating separate result sets, and then combining them when all cursors are complete.

Joshua Bell
  • 7,727
  • 27
  • 30