如果您认为 IN 本质上等同于field1 == propertyCode OR field2 == propertyCode
,那么你可以说 IN 只是使用 OR 的另一种方式。
IndexedDB 无法对单个请求执行 OR(并集)。
一般来说,您唯一的办法是执行单独的请求,然后将它们合并到内存中。一般来说,这不会有很好的性能。如果您正在处理很多对象,您可能需要考虑完全放弃这种方法,并考虑如何避免这种方法。
另一种方法是迭代内存中的所有对象,然后过滤那些不符合条件的对象。再次,糟糕的表现。
这是一个花哨的技巧,可能会给你带来不错的性能,但它需要一些额外的工作和一点点存储开销:
- 在您的对象中存储一个额外的字段。例如,计划使用名为
hasPropertyCodeX
.
- 每当 3 个属性中的任何一个为 true(具有正确的代码)时,请设置该字段(如,只需将其设为对象的属性,其值无关紧要)。
- 当 3 个属性都不为 true 时,从对象中删除该属性。
- 每当修改对象时,请更新派生属性(根据需要设置或取消设置它)。
- 在indexedDB 中对此派生属性创建索引。
- 在索引上打开光标。只有具有属性的对象才会出现在光标结果中。
第三种方法的示例
var request = indexedDB.open(...);
request.onupgradeneeded = upgrade;
function upgrade(event) {
var db = event.target.result;
var store = db.createObjectStore('store', ...);
// Create another index for the special property
var index = store.createIndex('hasPropCodeX', 'hasPropCodeX');
}
function putThing(db, thing) {
// Before storing the thing, secretly update the hasPropCodeX value
// which is derived from the thing's other properties
if(thing.field1 === 'propCode' || thing.field2 === 'propCode' ||
thing.field3 === 'propCode') {
thing.hasPropCodeX = 1;
} else {
delete thing.hasPropCodeX;
}
var tx = db.transaction('store', 'readwrite');
var store = tx.objectStore('store');
store.put(thing);
}
function getThingsWherePropCodeXInAnyof3Fields(db, callback) {
var things = [];
var tx = db.transaction('store');
var store = tx.objectStore('store');
var index = store.index('hasPropCodeX');
var request = index.openCursor();
request.onsuccess = function(event) {
var cursor = event.target.result;
if(cursor) {
var thing = cursor.value;
things.push(thing);
cursor.continue();
} else {
callback(things);
}
};
request.onerror = function(event) {
console.error(event.target.error);
callback(things);
};
}
// Now that you have an api, here is some example calling code
// Not bothering to promisify it
function getData() {
var request = indexedDB.open(...);
request.onsuccess = function(event) {
var db = event.target.result;
getThingsWherePropCodeXInAnyof3Fields(db, function(things) {
console.log('Got %s things', things.length);
for(let thing of things) {
console.log('Thing', thing);
}
});
};
}