使用 IndexedDB Like SQL。使用不在范围内的多个索引值进行查询
Using IndexedDB Like SQL. Query with multiple index values that are not in a range
基本上我想 select 所有匹配 index/key 的值,但它们不在编程范围内。它必须能够 select 一系列请求(一次数量可变)。在 SQL 我会这样做。
Select * FROM questions WHERE `id` in (2,45,17)
但是当谈到 indexedDB 时,我的选择似乎很有限。我发现我可以连续执行多个请求,但如果事先不知道要选择多少个请求,我该怎么做呢?
这是我目前使用的JavaScript。显然这是行不通的。我已经创建了一个名为 "practice_materials" 的 indexedDB 数据库,创建了一个名为 "questions" 的 objectstore,通过 id 建立了索引,并将数据放入其中。
window.idb=window.indexedDB;
var request=indexedDB.open(db_name,db_version);
request.onerror=function(event){
console.log('error:'+event);
}
request.onsuccess=function(event){
db_res=request.result;
}
var tx=db_res.transaction([obj_store]).objectStore(obj_store);
var res='';
var out_obj=[];
var id=[2,45,17];
for(i=0;i<3;++i){
request=tx.get(id[i]);
request.onsuccess=function(event){
out_obj.push(request.result);
}
}
对于以后遇到这个问题的人。利用 idb 摆脱回调地狱,这样您就可以让代码等到 database/other 事务完成后再尝试访问它。
https://github.com/jakearchibald/idb
唯一的事情是你必须为你的浏览器构建它,这是值得的,因为它有承诺并且能够等到交易完成。(主要是在打开数据库,获取索引时,select ing objectstore 等,数据的设置并不重要,但它仍然很好。
P.S。
我将把它用于问答系统,作为解剖学学生的学习助手。它将 select 从每一章(我做的)中随机抽取一些问题,范围是 15-25,问题是随机 select 抽取的。我会利用 WebSQL,因为我可以更轻松地做到这一点,但我很感激。
P.P.S。
除了正确答案的 +Rep 之外,我还会在这个问题上加上 link。
没有直接途径来模拟 SQL in
语句。这里有两个解决方案。
使用Array.prototype.filter()
(有人可能会说两行代码很简单)
const filter = [2,45,17];
const fieldToFilter = "someField";
objectStore.getAll().onsuccess = function(event) {
const filtered = event.target.result.filter(i => filter.includes(i[fieldToFilter]));
console.log(filtered);
};
使用 IndexDB 游标:
归因:改编自:Here
let i = 0;
const selected = [];
const filter = [2,17,45];
myIndex.openCursor(keyRangeValue).onsuccess = function(event) {
let cursor = event.target.result;
if (!cursor) { // We are done
console.log(selected); // do something with result
return;
}
var key = cursor.key;
if (key > filter[i]) { // filter should be sorted asc
++i;
if (i >= filter.length) {
return;
}
}
if (key === filter[i]) { // Use individual row
selected.push(cursor.value); // here
cursor.continue(); // Next
} else {
cursor.continue(filter[i]); // Go to the next filtered key
}
}
基本上我想 select 所有匹配 index/key 的值,但它们不在编程范围内。它必须能够 select 一系列请求(一次数量可变)。在 SQL 我会这样做。
Select * FROM questions WHERE `id` in (2,45,17)
但是当谈到 indexedDB 时,我的选择似乎很有限。我发现我可以连续执行多个请求,但如果事先不知道要选择多少个请求,我该怎么做呢?
这是我目前使用的JavaScript。显然这是行不通的。我已经创建了一个名为 "practice_materials" 的 indexedDB 数据库,创建了一个名为 "questions" 的 objectstore,通过 id 建立了索引,并将数据放入其中。
window.idb=window.indexedDB;
var request=indexedDB.open(db_name,db_version);
request.onerror=function(event){
console.log('error:'+event);
}
request.onsuccess=function(event){
db_res=request.result;
}
var tx=db_res.transaction([obj_store]).objectStore(obj_store);
var res='';
var out_obj=[];
var id=[2,45,17];
for(i=0;i<3;++i){
request=tx.get(id[i]);
request.onsuccess=function(event){
out_obj.push(request.result);
}
}
对于以后遇到这个问题的人。利用 idb 摆脱回调地狱,这样您就可以让代码等到 database/other 事务完成后再尝试访问它。
https://github.com/jakearchibald/idb
唯一的事情是你必须为你的浏览器构建它,这是值得的,因为它有承诺并且能够等到交易完成。(主要是在打开数据库,获取索引时,select ing objectstore 等,数据的设置并不重要,但它仍然很好。 P.S。 我将把它用于问答系统,作为解剖学学生的学习助手。它将 select 从每一章(我做的)中随机抽取一些问题,范围是 15-25,问题是随机 select 抽取的。我会利用 WebSQL,因为我可以更轻松地做到这一点,但我很感激。
P.P.S。 除了正确答案的 +Rep 之外,我还会在这个问题上加上 link。
没有直接途径来模拟 SQL in
语句。这里有两个解决方案。
使用Array.prototype.filter()
(有人可能会说两行代码很简单)
const filter = [2,45,17];
const fieldToFilter = "someField";
objectStore.getAll().onsuccess = function(event) {
const filtered = event.target.result.filter(i => filter.includes(i[fieldToFilter]));
console.log(filtered);
};
使用 IndexDB 游标:
归因:改编自:Here
let i = 0;
const selected = [];
const filter = [2,17,45];
myIndex.openCursor(keyRangeValue).onsuccess = function(event) {
let cursor = event.target.result;
if (!cursor) { // We are done
console.log(selected); // do something with result
return;
}
var key = cursor.key;
if (key > filter[i]) { // filter should be sorted asc
++i;
if (i >= filter.length) {
return;
}
}
if (key === filter[i]) { // Use individual row
selected.push(cursor.value); // here
cursor.continue(); // Next
} else {
cursor.continue(filter[i]); // Go to the next filtered key
}
}