我要执行此查询
从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;


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

最佳答案

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

IndexedDB无法对单个请求执行OR(联合)。

通常,您唯一的办法是执行单独的请求,然后将其合并到内存中。通常,这不会有很好的性能。如果要处理许多对象,则可能要考虑完全放弃这种方法,并考虑如何避免这种方法。

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

这是个花哨的技巧,可能会给您带来不错的性能,但是需要一些额外的工作和少量的存储开销:

  • 在您的对象中存储一个额外的字段。例如,计划使用一个名为hasPropertyCodeX的属性。
  • 只要这三个属性中的任何一个为true(具有正确的代码),就设置字段(例如,仅使其成为对象的属性,则其值无关紧要)。
  • 如果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);
          }
        });
      };
    }
    

    07-28 08:18