In my project I'm using browser's indexed-DB and I would like to retrieve some objects from the db with specific ids. According to MDN you could use ranges to get the results you want:
According to MDN:
// Only match "Donna"
var singleKeyRange = IDBKeyRange.only("Donna");
// Match anything past "Bill", including "Bill"
var lowerBoundKeyRange = IDBKeyRange.lowerBound("Bill");
// Match anything past "Bill", but don't include "Bill"
var lowerBoundOpenKeyRange = IDBKeyRange.lowerBound("Bill", true);
// Match anything up to, but not including, "Donna"
var upperBoundOpenKeyRange = IDBKeyRange.upperBound("Donna", true);
// Match anything between "Bill" and "Donna", but not including "Donna"
var boundKeyRange = IDBKeyRange.bound("Bill", "Donna", false, true);
// To use one of the key ranges, pass it in as the first argument of openCursor()/openKeyCursor()
index.openCursor(boundKeyRange).onsuccess = function(event) {
var cursor = event.target.result;
if (cursor) {
// Do something with the matches.
cursor.continue();
}
};
However what do you do if you wish to get an array of specific ids that are not in order and are not sequential (ex:[91,819,34,24,501]) with a single request?
More specifically, IndexedDB data is stored in the browser profile folder.
It lets you store just about anything in the user's browser. In addition to the usual search, get, and put actions, IndexedDB also supports transactions. Here is the definition of IndexedDB on MDN: "IndexedDB is a low-level API for client-side storage of significant amounts of structured data, including files/blobs.
IndexedDB is a low-level API for the client-side storage of significant amounts of structured data, including files/blobs. This API uses indexes to enable high-performance searches of this data.
You can't do this with a single request, but you can fire off multiple requests in parallel:
var keys = [91,819,34,24,501];
var results = [];
keys.forEach(function(key) {
store.get(key).onsuccess = function(e) {
results.push(e.target.result);
if (results.length === keys.length) {
// you're done!
}
};
});
Note that requests are required to execute in order, so the order of the results
array will match the order of the keys
array. If a key is not found, the corresponding result index will contain undefined
.
(There's a feature request for Indexed DB to support this directly: https://github.com/w3c/IndexedDB/issues/19 but no final API design yet.)
Based on your comment, it sounds like you want to do something like SELECT objects FROM objects WHERE object.id = 1 OR object.id = 2 OR object.id = 5
, as a single query (request). Unfortunately, indexedDB cannot do OR
style queries (unions). It can only do AND
style queries (intersections).
There is a possible solution if the various ids you want to retrieve are known a-priori. You can simply store an additional group-id property, put the related ids into distinct groups, and then query by group-id. This obviously does not work if the ids you want to retrieve overlap (appear in more than one group), or are variable (object to group membership changes from query to query).
Getting multiple objects by keys in 1 go is possible by using a cursor.
The keys need to be sorted.
var keys = [91,819,34,24,501].sort(function(a, b) {
return a - b;
});
var results = [];
var i = 0;
var cursorReq = store.openCursor();
cursorReq.onsuccess = function(e) {
var c = e.target.result;
if(!c) { return; /* done */ }
while(c.key > keys[i]) {
i++;
if(i === keys.length) { return; /* done */ }
}
if(c.key === keys[i]) { // found
results.push(cursor.value);
c.continue();
} else { c.continue(keys[i]); }
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With