有没有办法在indexedDB中使用复合/复合键进行排序?

时间:2013-10-31 19:12:36

标签: indexeddb

How to use IndexedDB count method with composite keys?中,我学会了如何过滤单个属性。到目前为止,这么好,但现在我需要同时排序和过滤。

我的对象存储空间充满了这些对象:

os.put({feed_id:1,id:1,title:"foofoo",time:111});
os.put({feed_id:1,id:2,title:"foobar",time:112});
os.put({feed_id:1,id:3,title:"foobaz",time:113});
os.put({feed_id:3,id:1,title:"bazfoo",time:114});
os.put({feed_id:3,id:2,title:"bazbar",time:115});
os.put({feed_id:3,id:3,title:"bazbaz",time:116});
os.put({feed_id:1,id:4,title:"foofoo",time:122});
os.put({feed_id:1,id:5,title:"foobar",time:121});
os.put({feed_id:1,id:6,title:"foobaz",time:120});
os.put({feed_id:3,id:4,title:"bazfoo",time:119});
os.put({feed_id:3,id:5,title:"bazbar",time:118});
os.put({feed_id:3,id:6,title:"bazbaz",time:117});

我在对象存储上设置了两个索引,一个(idx_feedid)具有keyPath feed_id,这允许我使用openCursor获取具有特定feed id的所有对象,并使用keyPath {获取一个(idx_ts) {1}}。

问题是迭代idx_feedid的结果会给我结果而不对时间戳进行排序。在SQL中,我很容易做["id","feed_id","time"],但是如何在IndexedDB中做到这一点?

我如何限制返回的结果以实现分页?从本质上讲,我需要像MySQL SELECT * FROM feeditems WHERE feed_id=3 ORDER BY time DESC / LIMIT 0,10 / ...

这样的东西

2 个答案:

答案 0 :(得分:0)

不能做限制。即使您尝试,内部实现也会使用您无法控制的优化,例如始终将前100行加载到RAM中,即使您只需要1.幸运的是,小规模应用程序不会受此影响太大,因为它还是很快。

关于您的问题,请查看https://developer.mozilla.org/en-US/docs/Web/API/IDBObjectStore?redirectlocale=en-US&redirectslug=IndexedDB%2FIDBObjectStore#openCursor()。在Feed id 3上设置IDBKeyRange,并按照'prev'的方向传递以按降序迭代。

编辑:要进行分页,你可以使用cursor.advance(+或 - n行)

答案 1 :(得分:-1)

使用复合索引,['feed_id','time']并在反方向上查询IDBKeyRange.only([3])。

使用我的open source library,如下所示:

var schema = {
  stores: [{
    name: 'os',
    indexes: [{
      name: 'feed_id, time',
      keyPath: ['feed_id', 'time']
    }]
  }]
}

var db = new ydn.db.Storage('db name', schema);
var kr = ydn.db.KeyRange.starts([3]);
db.values('os', 'feed_id, time', kr, 10, 0, true).done(function(values) {
  console.log(values); // sorted by descending of time
});

该库支持indexeddb和websql,没有任何依赖性。您还将在websql上看到非常快的性能。

如果使用填充程序,复合索引可能无法正常工作。