【问题标题】:IN Operator equivalence in indexedDB在 indexedDB 中的 IN 运算符等价
【发布时间】:2016-08-31 12:31:13
【问题描述】:

我想执行这个查询 select * from properties where propertyCode IN ("field1", "field2", "field3")

如何在 IndexedDB 中实现这一点 我试过这个东西

getData : function (indexName, params, objectStoreName) {
            var defer = $q.defer(),
                db, transaction, index, cursorRequest, request, objectStore, resultSet, dataList = [];
            request = indexedDB.open('test');
            request.onsuccess = function (event) {
                db = request.result;
                transaction = db.transaction(objectStoreName);
                objectStore = transaction.objectStore(objectStoreName);
                index = objectStore.index(indexName);
                cursorRequest = index.openCursor(IDBKeyRange.only(params));
                cursorRequest.onsuccess = function () {

                    resultSet = cursorRequest.result;
                    if(resultSet){
                        dataList.push(resultSet.value);
                        resultSet.continue();
                    }
                    else{
                        console.log(dataList);
                        defer.resolve(dataList);
                    }
                };

                cursorRequest.onerror = function (event) {
                    console.log('Error while opening cursor');
                }
            }
            request.onerror = function (event) {
                console.log('Not able to get access to DB in executeQuery');
            }
            return defer.promise;

但是没有用。我尝试了谷歌,但找不到确切的答案。

【问题讨论】:

  • 什么是objectStore?以及你定义它的地方
  • 我已经更新了代码..请检查
  • 你传递的参数是什么? IDBKeyRange.only() 产生一个只跨越一个键的范围。所以这个游标只会产生一条记录。如果您打算将参数作为要获取的键列表,您可以简单地遍历参数并为每个参数发出一个 get()。
  • 如何迭代列表?你能写一个示例代码吗?

标签: javascript range indexeddb


【解决方案1】:

如果您认为 IN 本质上等同于 field1 == propertyCode OR field2 == propertyCode,那么您可以说 IN 只是使用 OR 的另一种方式。

IndexedDB 不能对单个请求执行 OR(联合)。

一般来说,您唯一的办法是执行单独的请求,然后将它们合并到内存中。一般来说,这不会有很好的表现。如果您要处理大量对象,您可能需要考虑完全放弃这种方法并考虑如何避免这种方法。

另一种方法是遍历内存中的所有对象,然后过滤那些不符合条件的对象。再次,糟糕的表现。

这是一个花哨的 hack,可能会给你带来不错的性能,但它需要一些额外的工作和一点点存储开销:

  • 在您的对象中存储一个额外的字段。例如,计划使用名为 hasPropertyCodeX 的属性。
  • 只要 3 个属性中的任何一个为真(具有正确的代码),就设置字段(如,只需将其设为对象的属性,其值无关紧要)。
  • 当 3 个属性都不为真时,从对象中删除该属性。
  • 每当修改对象时,更新派生属性(根据需要设置或取消设置)。
  • 在 indexedDB 中为此派生属性创建索引。
  • 在索引上打开光标。只有具有属性的对象才会出现在光标结果中。

第三种方法的示例

var request = indexedDB.open(...);
request.onupgradeneeded = upgrade;

function upgrade(event) {
  var db = event.target.result;
  var store = db.createObjectStore('store', ...);

  // Create another index for the special property
  var index = store.createIndex('hasPropCodeX', 'hasPropCodeX');
}

function putThing(db, thing) {

  // Before storing the thing, secretly update the hasPropCodeX value
  // which is derived from the thing's other properties
  if(thing.field1 === 'propCode' || thing.field2 === 'propCode' || 
    thing.field3 === 'propCode') {
    thing.hasPropCodeX = 1;
  } else {
    delete thing.hasPropCodeX;
  }

  var tx = db.transaction('store', 'readwrite');
  var store = tx.objectStore('store');
  store.put(thing);
}

function getThingsWherePropCodeXInAnyof3Fields(db, callback) {
  var things = [];
  var tx = db.transaction('store');
  var store = tx.objectStore('store');
  var index = store.index('hasPropCodeX');
  var request = index.openCursor();
  request.onsuccess = function(event) {
    var cursor = event.target.result;
    if(cursor) {
      var thing = cursor.value;
      things.push(thing);
      cursor.continue();
    } else {
      callback(things);
    }
  };
  request.onerror = function(event) {
    console.error(event.target.error);
    callback(things);
  };
}

// Now that you have an api, here is some example calling code
// Not bothering to promisify it
function getData() {
  var request = indexedDB.open(...);
  request.onsuccess = function(event) {
    var db = event.target.result;
    getThingsWherePropCodeXInAnyof3Fields(db, function(things) {
      console.log('Got %s things', things.length);
      for(let thing of things) {
        console.log('Thing', thing);
      }
    });
  };
}

【讨论】:

  • 感谢@Josh 的回复。但我无法做到这一点。你能写一个示例代码吗?这将是一个很大的帮助。
猜你喜欢
  • 1970-01-01
  • 2011-01-21
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2020-08-16
  • 1970-01-01
相关资源
最近更新 更多