像SQL一样使用IndexedDB。查询不在范围内的多个索引值

时间:2019-05-19 19:08:49

标签: javascript indexeddb database-indexes

基本上,我想选择所有与索引/键匹配的值,但它们不在编程范围内。它必须能够选择一定范围的请求(例如一次可变数量)。在SQL中,我会这样做。

Select * FROM questions WHERE `id` in (2,45,17)

但是当indexedDB出现时,我的选择似乎很有限。我发现我可以连续执行多个请求,但是在不知道事先要选择多少个请求的情况下该怎么做?

这是我正在使用的当前JavaScript。显然,这是行不通的。我已经创建了一个名为“ practice_materials”的indexedDB数据库,创建了一个名为“ questions”的对象存储,通过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摆脱回调地狱,以便您可以尝试访问数据库之前,让代码等待数据库/其他事务完成。

https://github.com/jakearchibald/idb

唯一的事情是您必须为浏览器构建它,这是值得的,它可以保证并能够等到事务完成。(主要是在打开数据库,获取索引,选择对象存储等时,进行设置数据无关紧要,但仍然很不错。 附言 我将把它用于问答系统,作为面向解剖学学生的学习助手。它将从每个章节中随机选择一个问题(我所做的),范围是15-25,其中问题是随机选择的。我会使用WebSQL,因为我可能可以更轻松地完成此操作,但是人们对此表示赞赏。

P.P.S。 除了提供正确答案的+ Rep外,我还将提供指向该问题的链接。

1 个答案:

答案 0 :(得分:1)

没有直接途径可以模拟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
  }
}