从 Indexeddb 获取特定的 ID
Getting specific ids from Indexeddb
在我的项目中,我使用浏览器的索引数据库,我想从数据库中检索一些具有特定 ID 的对象。根据 MDN,您可以使用范围来获得您想要的结果:
根据 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();
}
};
但是,如果您希望通过单个请求获得一组无序且不连续的特定 ID(例如:[91,819,34,24,501]),您会怎么做?
根据您的评论,听起来您想像 SELECT objects FROM objects WHERE object.id = 1 OR object.id = 2 OR object.id = 5
这样的操作作为单个查询(请求)执行。不幸的是,indexedDB 不能做 OR
风格的查询(联合)。它只能进行 AND
样式查询(交叉点)。
如果您要检索的各种 ID 是先验已知的,则有一个可能的解决方案。您可以简单地存储一个额外的group-id 属性,将相关的id放入不同的组中,然后通过group-id进行查询。如果您要检索的 ID 重叠(出现在多个组中),或者是可变的(对象到组成员资格随查询的不同而变化),这显然不起作用。
您不能对单个请求执行此操作,但您可以并行触发多个请求:
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!
}
};
});
请注意,请求需要按顺序执行,因此 results
数组的顺序将与 keys
数组的顺序一致。如果没有找到key,对应的结果索引会包含undefined
。
(索引数据库有直接支持此功能的功能请求:https://github.com/w3c/IndexedDB/issues/19 但还没有最终的 API 设计。)
使用游标可以一键获取多个对象。
键需要排序。
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]); }
}
在我的项目中,我使用浏览器的索引数据库,我想从数据库中检索一些具有特定 ID 的对象。根据 MDN,您可以使用范围来获得您想要的结果:
根据 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();
}
};
但是,如果您希望通过单个请求获得一组无序且不连续的特定 ID(例如:[91,819,34,24,501]),您会怎么做?
根据您的评论,听起来您想像 SELECT objects FROM objects WHERE object.id = 1 OR object.id = 2 OR object.id = 5
这样的操作作为单个查询(请求)执行。不幸的是,indexedDB 不能做 OR
风格的查询(联合)。它只能进行 AND
样式查询(交叉点)。
如果您要检索的各种 ID 是先验已知的,则有一个可能的解决方案。您可以简单地存储一个额外的group-id 属性,将相关的id放入不同的组中,然后通过group-id进行查询。如果您要检索的 ID 重叠(出现在多个组中),或者是可变的(对象到组成员资格随查询的不同而变化),这显然不起作用。
您不能对单个请求执行此操作,但您可以并行触发多个请求:
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!
}
};
});
请注意,请求需要按顺序执行,因此 results
数组的顺序将与 keys
数组的顺序一致。如果没有找到key,对应的结果索引会包含undefined
。
(索引数据库有直接支持此功能的功能请求:https://github.com/w3c/IndexedDB/issues/19 但还没有最终的 API 设计。)
使用游标可以一键获取多个对象。
键需要排序。
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]); }
}