IndexedDB中的OR或IN操作

时间:2014-03-15 04:52:35

标签: indexeddb

有没有办法在IndexedDB中对同一个属性进行OR或IN查询?

另一个词,我如何得到结果,

SELECT * FROM MyTable WHERE columnA IN ('ABC','DFT') AND columnB = '123thd'

谢谢!

4 个答案:

答案 0 :(得分:5)

在多次请求期间,没有办法开箱即用ORIN - 类似查询。通常,像这样的问题的模式是“超出范围”,然后根据需要提取更多条目,并将其过滤到完全匹配。"

Chrome小组has proposed openKeyCursor()方法作为此类查询的解决方案(感谢Kyaw Tun的建议,SO的参与者和作者ydn),但它并非标准,也未在其他浏览器中采用。

我能想到的最佳解决方案类似于w3线程的Comment #4

  • 使用值' 123thd'在columnB上打开确切的关键光标
  • 对所有这些记录进行游标,匹配columnA值的对象' ABC'和' DFT'

如果您通常希望结果数量为columnB是' 123thd'非常大,而且大多数人都没有价值观和ABC'或者' DFT',那么你可能需要打开两个游标 - 一个在columnA w / value' ABC'另一个有价值的DFT'。这是一种更复杂的方法,因为您必须手动合并两个结果集。

答案 1 :(得分:1)

使用复合索引进行2次连续查询的解决方案:

  1. 在columnA和columnB上创建复合索引。有关示例,请参阅this post
  2. 使用范围参数['ABC','123thd']进行查询并迭代其结果。
  3. 使用范围参数['DFT','123thd']进行查询并迭代其结果。
  4. 使用派生属性进行1次查询的解决方案:

    这种方法的缺点是你需要知道你计划执行的查询 必须为每个查询调整此方法。这是你应该做的事情 用SQL。不幸的是,因为许多开发人员不打扰正确的查询规划,所以这并不是那么明显,所以这就像在使用indexedDB之前学习和开始使用一样。但是,正确的查询计划确实会产生更好的性能。

    // In onupgradeneeded
    function myOnUpgradeNeeded(event) {
      var db = event.target.result;
      var store = db.createObjectStore('MyTable');
    
      // Create a compound index on the derived property of columnA
      // and the normal property of columnB
      store.createIndex('A_ABC_OR_DFT_AND_B', ['ABC_OR_DFT_FLAG','columnB']);
    }
    
    
    function wrappedPut(db, obj, callback) {
      // Set the flag property
      // indexedDB cannot index booleans, so we use simple integer representation
      // where 1 represents true, 0 represents false. But we can go further since
      // we know that undefined properties dont appear in the index.
    
     if(obj.columnA=='ABC'||obj.columnA=='DFT') {
       obj.ABC_OR_DFT_FLAG = 1;
     } else {
       delete obj.ABC_OR_DFT_FLAG;
     }
    
     put(db, obj, callback);
    }
    
    // In your add/update function
    function put(db, obj, callback) {
     db.transaction('MyTable','readwrite').objectStore('myTable').put(obj).onsuccess = callback;
    }
    
    // Voila, a single efficient high speed query over all items 
    // in MyTable where columnA is ABC or DFT and where columnB 
    // is 123thd, using a single index, without using a 3rd party
    // library, and without doing some horrible double cursor stuff
    // in javascript, and just using the indexedDB API.
    function runTheABCDFT123Query(db, onSuccess, onComplete) {
      var tx = db.transaction('MyTable');
      tx.onComplete = onComplete;
      tx.objectStore('MyTable').index('A_ABC_OR_DFT_AND_B').openCursor(
        IDBKeyRange.only([1,'123thd'])).onsuccess = function(event) {
        if(event.target) {
          onSuccess(event.target.value);
          event.target.continue();
        }
      };
    }
    

答案 2 :(得分:0)

indexedDB API中不存在此功能。您只能过滤单个索引。您可以尝试围绕indexedDB API编写的库之一。其中一些提供了额外的过滤功能。

答案 3 :(得分:0)

这是一个简单的查询,相当于使用JsStore Library

的sql查询
var Connection = new JsStore.Instance("MyDatabase");
Connection.select({
    From: "MyTable",
    Where:{
        columnA : {In:['ABC','DFT')]},
        columnB : '123thd'
    },
    OnSuccess:function (results){
        console.log(results);
    },
    OnError:function (error) {
        console.log(error);
    }
});

希望这会节省你的时间和代码:)。