我需要能够以三种不同的方式从IndexedDB过滤一些数据。
例如,如果数据是从以下对象存储的:
var cars = [
{type: 'econmoy',colour: 'red',ageRange:'1 - 10'},
{type: 'econmoy',colour: 'blue',ageRange:'11 - 20'},
{type: 'luxury',colour: 'yellow',ageRange:'1 - 10'}
]
我想允许用户分别和/或联合按类型,颜色和ageRange过滤结果。我希望 IDBKeyRange.bound 方法是答案,但这不起作用:
var lowerArray = ['econmoy','blue','1 - 10'];
var upperArray = ['luxury','yellow','11 - 20'];
var rangeTest = IDBKeyRange.bound(lowerArray,upperArray);
index.openCursor(rangeTest).onsuccess = ...
有人能提出一个很好的方法吗?
这是我最初想法的一个粗略的小提示:http://jsfiddle.net/As55S/
任何反馈意见。
答案 0 :(得分:1)
您的示例似乎运行良好,不幸的是 AFAIK ,您无法在索引数组上过滤单独多个属性。
整个indexedDB过滤器处理依赖于索引键的顺序。 复合索引键必须被视为多个值的简单连接,因此您可以使用它们进行搜索,但是您需要遵守属性顺序...
在您的示例中,复合索引顺序为 type => color => ageRange ...
objectStore.createIndex("name", ['type','colour','ageRange'], { unique: false });
所以你可以搜索:
但您无法像在关系数据库中那样过滤单独 颜色和 ageRange 。我个人没有办法做到这一点,但这里有三种可能的丑陋解决方法:
在整个Object存储上执行游标,并过滤游标循环中的每个对象。最容易编码,你将能够进行更复杂的过滤(startWith / endWith),但它会变慢,特别是需要大量的行来浏览......
(提示:如果强制用户将最后一个特定字段绑定到索引,可以使此方法更快,以减少要从游标中过滤的行的数量...... )
为每个属性订单创建复合索引,并根据搜索字段值使用正确的索引。它会为你的对象产生大量的代码和索引,但根据this comment,单个对象存储的20个索引是合理的,所以你可以支持至少4个搜索字段......
< / LI>[编辑:根据你的评论 - 我可能会误解]
为每个属性创建一个标准索引,并使用index cursor单独使用它们来获取它们的主键,然后通过仅保留每个索引查询中找到的主键将结果合并到一个数组中。最后,从数组中合并的主键逐个加载相应的对象。
这种方式可能非常好,因为您不必创建和 管理很多索引,每个字段都支持 startWith 过滤。但你放松了直的光标功能,我想知道 从每个记录逐个加载的性能是什么 JS?
无论如何,我认为IndexedDB并不适合这样的用例。 如果您计划进行一些复杂的搜索(多标准查询,统计...),那么关系数据库(如WebSQL)通常更合适。