有没有办法在IndexedDB中对同一个属性进行OR或IN查询?
另一个词,我如何得到结果,
SELECT * FROM MyTable WHERE columnA IN ('ABC','DFT') AND columnB = '123thd'
谢谢!
答案 0 :(得分:5)
在多次请求期间,没有办法开箱即用OR
或IN
- 类似查询。通常,像这样的问题的模式是“超出范围”,然后根据需要提取更多条目,并将其过滤到完全匹配。"
Chrome小组has proposed openKeyCursor()
方法作为此类查询的解决方案(感谢Kyaw Tun的建议,SO的参与者和作者ydn),但它并非标准,也未在其他浏览器中采用。
我能想到的最佳解决方案类似于w3线程的Comment #4:
columnB
上打开确切的关键光标columnA
值的对象' ABC'和' DFT' 如果您通常希望结果数量为columnB
是' 123thd'非常大,而且大多数人都没有价值观和ABC'或者' DFT',那么你可能需要打开两个游标 - 一个在columnA
w / value' ABC'另一个有价值的DFT'。这是一种更复杂的方法,因为您必须手动合并两个结果集。
答案 1 :(得分:1)
使用复合索引进行2次连续查询的解决方案:
使用派生属性进行1次查询的解决方案:
这种方法的缺点是你需要知道你计划执行的查询 必须为每个查询调整此方法。这是你应该做的事情 用SQL。不幸的是,因为许多开发人员不打扰正确的查询规划,所以这并不是那么明显,所以这就像在使用indexedDB之前学习和开始使用一样。但是,正确的查询计划确实会产生更好的性能。
// In onupgradeneeded
function myOnUpgradeNeeded(event) {
var db = event.target.result;
var store = db.createObjectStore('MyTable');
// Create a compound index on the derived property of columnA
// and the normal property of columnB
store.createIndex('A_ABC_OR_DFT_AND_B', ['ABC_OR_DFT_FLAG','columnB']);
}
function wrappedPut(db, obj, callback) {
// Set the flag property
// indexedDB cannot index booleans, so we use simple integer representation
// where 1 represents true, 0 represents false. But we can go further since
// we know that undefined properties dont appear in the index.
if(obj.columnA=='ABC'||obj.columnA=='DFT') {
obj.ABC_OR_DFT_FLAG = 1;
} else {
delete obj.ABC_OR_DFT_FLAG;
}
put(db, obj, callback);
}
// In your add/update function
function put(db, obj, callback) {
db.transaction('MyTable','readwrite').objectStore('myTable').put(obj).onsuccess = callback;
}
// Voila, a single efficient high speed query over all items
// in MyTable where columnA is ABC or DFT and where columnB
// is 123thd, using a single index, without using a 3rd party
// library, and without doing some horrible double cursor stuff
// in javascript, and just using the indexedDB API.
function runTheABCDFT123Query(db, onSuccess, onComplete) {
var tx = db.transaction('MyTable');
tx.onComplete = onComplete;
tx.objectStore('MyTable').index('A_ABC_OR_DFT_AND_B').openCursor(
IDBKeyRange.only([1,'123thd'])).onsuccess = function(event) {
if(event.target) {
onSuccess(event.target.value);
event.target.continue();
}
};
}
答案 2 :(得分:0)
indexedDB API中不存在此功能。您只能过滤单个索引。您可以尝试围绕indexedDB API编写的库之一。其中一些提供了额外的过滤功能。
答案 3 :(得分:0)
这是一个简单的查询,相当于使用JsStore Library
的sql查询var Connection = new JsStore.Instance("MyDatabase");
Connection.select({
From: "MyTable",
Where:{
columnA : {In:['ABC','DFT')]},
columnB : '123thd'
},
OnSuccess:function (results){
console.log(results);
},
OnError:function (error) {
console.log(error);
}
});
希望这会节省你的时间和代码:)。