我正在使用 dexie.js 与 IndexedDB 交互。我想知道是否可以一次使用多个索引进行排序或排序(例如 db.people.orderBy( index1, desc : index2, asc )...如果可能,正确的语法是什么?
问问题
1892 次
1 回答
1
要么使用复合索引,要么使用 Collection.and()。
如果你只能忍受 Chrome、Firefox 或 Opera,你可以使用复合索引。如果它必须在 Safari、IndexedDBShim、Edge 或 IE 上运行,那么您现在不能使用复合索引。虽然有一个shim可以为 IE/Edge 启用它,但它仍处于测试阶段,所以我建议在这些情况下使用 Collection.and()。
假设您有一个表单,用户可以在其中填写朋友的各种属性:
<form>
<input name="name"/>
<input name="age"/>
<input name="shoeSize" />
</form>
使用 Collection.and()
首先,选择最有可能开始搜索的索引。在这种情况下,“name”将是一个完美的索引,它不会匹配这么多的项目,而 age 或 shoeSize 可能会匹配更多的朋友。
架构:
db.version(X).stores({
friends: "id, name, age, shoeSize"
});
询问:
function prepareQuery () {
// Pick a good index. The picked index will filter out with IndexedDB's built-in keyrange
var query;
if (form.name.value) {
query = db.friends.where('name').equals(form.name.value);
} else if (form.age.value) {
query = db.friends.where('age').equals(parseInt(form.age.value));
} else if (form.shoeSize.value) {
query = db.friends.where('shoeSize').equals(parseInt(form.shoeSize.value));
} else {
query = db.friends.toCollection();
}
// Then manually filter the result. May filter a field that the DB has already filtered out,
// but the time that takes is negligible.
return query.and (function (friend) {
return (
(!form.name.value || friend.name === form.name.value) &&
(!form.age.value || friend.age == form.age.value) &&
(!form.shoeSize.value || friend.shoeSize == form.shoeSize.value));
});
}
// Run the query:
form.onsubmit = function () {
prepareQuery() // Returns a Collection
.limit(25) // Optionally add a limit onto the Collection
.toArray(function (result) { // Execute query
alert (JSON.stringify(result, null, 4));
})
.catch (function (e) {
alert ("Oops: " + e);
});
}
使用复合索引
如上所述,复合索引代码仅适用于基于 mozilla 和 chromium 的浏览器。
db.version(x).stores({
friends: "id, name, age, shoeSize," +
"[name+age+shoeSize]," +
"[name+shoeSize]," +
"[name+age]," +
"[age+shoeSize]"
});
使用复合索引时的 prepareQuery() 函数:
function prepareQuery() {
var indexes = []; // Array of Array[index, key]
if (form.name.value)
indexes.push(["name", form.name.value]);
if (form.age.value)
indexes.push(["age", parseInt(form.age.value)]);
if (form.shoeSize.value)
indexes.push(["shoeSize", parseInt(form.shoeSize.value)]);
var index = indexes.map(x => x[0]).join('+'),
keys = indexes.map(x => x[1]);
if (indexes.length === 0) {
// No field filled in. Return unfiltered Collection
return db.friends.toCollection();
} else if (indexes.length === 1) {
// Single field filled in. Use simple index:
return db.friends.where(index).equals(keys[0]);
} else {
// Multiple fields filled in. Use compound index:
return db.friends.where("[" + index + "]").equals(keys);
}
}
// Run the query:
form.onsubmit = function () {
prepareQuery() // Returns a Collection
.limit(25) // Optionally add a limit onto the Collection
.toArray(function (result) { // Execute query
alert (JSON.stringify(result, null, 4));
})
.catch (function (e) {
alert ("Oops: " + e);
});
}
在此处使用箭头函数使其更具可读性。此外,您的目标是铬或火狐,他们已经支持它。
于 2016-04-11T10:23:26.843 回答