在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
/ ...
答案 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上看到非常快的性能。
如果使用填充程序,复合索引可能无法正常工作。