10

I'm using a cursor with a lower bound range query. I can't find a way to limit the number of objects returned, similar to a "LIMIT n" clause in a databse.

var keyRange = IDBKeyRange.lowerBound('');

Does it not exist ?

Philippe Girolami
  • 1,876
  • 1
  • 13
  • 15

3 Answers3

11

As you're iterating through the results, you can stop at any time. Something like this should work:

var results = [];
var limit = 20;
var i = 0;

objectStore.openCursor().onsuccess = function (event) {
  var cursor = event.target.result;
  if (cursor && i < limit) {
    results.push(cursor.value);
    i += 1;
    cursor.continue();
  }
  else {
    // Do something with results, which has at most 20 entries
    console.log(results);
  }
};

Also, in the special case where you are selecting based on a key that is made up of sequential numbers, you could use a keyRange to explicitly return only a certain range. But that's generally not the case.

dumbmatter
  • 9,351
  • 7
  • 41
  • 80
  • 1
    exactly, it's not my case. I implemented what you describe above but in my case the object store is quite large so it's really dumb to retrieve all the data from it... hence my question... – Philippe Girolami Aug 28 '12 at 21:25
  • The code I posted isn't retrieving all the data, just the first 20 objects. – dumbmatter Aug 29 '12 at 04:37
  • 1
    Yes you're right but is the cursor streaming the data out of the DB ? It may be preloading everything before handling it back to the JS engine. For example, the MySQL driver for Java does that. – Philippe Girolami Aug 29 '12 at 08:42
  • Not that I've studied the source code of Chrome and Firefox to validate this, but it is supposed to be streaming the data out as you request it. I would be quite surprised if that wasn't the case. – dumbmatter Aug 29 '12 at 14:37
  • 3
    Chrome uses heuristics to preload up to 100 objects. – dgrogan Aug 30 '12 at 01:25
2

An important fix its replace:

if (cursor && i < limit) {

for

if (cursor && results.length < limit) {

Remember that its an async call, and it could be adding elements on "results" at the same time and "i" would not have the proper value.

0

You can even search by range in indexedDB with IDBKeyRange.bound function

IDBKeyRange.bound(keyValueFrom, keyValueTo, false, true);

You can set the start value, end value and if you should include the start and end value in the returned items. In my case i want the first value of the range, however i want to exclude the last value.

For details of IDBKeyRange please visit the W3C IndexedDB page

Deni Spasovski
  • 4,004
  • 3
  • 35
  • 52