如何在 IndexedDB 中创建具有多个条件的查询
How to create a query with multiple conditions in IndexedDB
我有一个包含多个索引的商店,我想查询。为了这个例子,假设我有一个带有 user_id 索引和 create_date 的消息存储,它是时间戳(并且假设我有索引 - user_id / create_date / user_id, create_date
我知道如何通过id查询用户:
var range = IDBKeyRange.only('123');
store.index('user_id').openCursor(range).onsuccess= function(e){....};
而且我知道如何按日期查询:
var range = IDBKeyRange.lowerBound(Date.now()-24 * 60 * 1000))
store.index('create_data').openCursor(range).onsuccess = function(e){....};
购买 我不知道如何一起查询。我知道我可以使用 JS 来解析这两个结果中的任何一个,但我想知道是否可以使用 IDB 来执行此操作。
编辑 - 我想做的伪查询是
user_id=123 AND create_date < (NOW() - 24 * 60 * 1000)
谢谢!
答案是使用IDBKeyRange.bound
:
var range = IDBKeyRange.bound(['123'],['123', Date.now()-10*1000]);
store.index('user_id,create_date').getCursor(range).onsuccess = function(e){...}
基本上,所有 IDBKeyRange 范围都可以使用 bound
范围来表示,因此通过使用多个值,我们可以创建我们想要的任何复合范围
下面是一个工作示例。
<!DOCTYPE html>
<html lang="en">
<head>
<title>Whosebug</title>
<script type="text/javascript" charset="utf-8">
var db_handler = null;
var dbDeleteRequest = window.indexedDB.deleteDatabase("toDoList");
dbDeleteRequest.onerror = function(event) {
console.log("Error while deleting database.", true);
};
dbDeleteRequest.onsuccess = function(event) {
// Let us open our database
var DBOpenRequest = window.indexedDB.open("toDoList", 5);
DBOpenRequest.onsuccess = function(event) {
console.log('<li>Database initialised.</li>');
// store the result of opening the database in the db variable. This is used a lot below
db_handler = DBOpenRequest.result;
// Run the addData() function to add the data to the database
addData();
};
DBOpenRequest.onupgradeneeded = function(event) {
console.log('<li>DBOpenRequest.onupgradeneeded</li>');
var db = event.target.result;
db.onerror = function(event) {
console.log('<li>Error loading database.</li>');
};
// Create an objectStore for this database //, { keyPath: "taskTitle" }); { autoIncrement : true }
var objectStore = db.createObjectStore("toDoList", { autoIncrement : true });
// define what data items the objectStore will contain
objectStore.createIndex("user_id", "user_id", { unique: false });
objectStore.createIndex("create_data", "create_data", { unique: false });
objectStore.createIndex("tags",['user_id','create_data'], {unique:false});
};
};
function addData() {
// Create a new object ready to insert into the IDB
var newItem = [];
newItem.push({ user_id: "101", create_data: (1000)});
newItem.push({ user_id: "102", create_data: (Date.now() - 18 * 60 * 1000)});
newItem.push({ user_id: "103", create_data: (Date.now() - 18 * 60 * 1000)});
newItem.push({ user_id: "101", create_data: (2000)});
newItem.push({ user_id: "101", create_data: (989)});
newItem.push({ user_id: "104", create_data: (Date.now() - 18 * 60 * 1000)});
console.log(newItem);
// open a read/write db transaction, ready for adding the data
var transaction = db_handler.transaction(["toDoList"], "readwrite");
// report on the success of opening the transaction
transaction.oncomplete = function(event) {
console.log('<li>Transaction completed: database modification finished.</li>' + new Date());
};
transaction.onerror = function(event) {
console.log('<li>Transaction not opened due to error. Duplicate items not allowed.</li>');
};
// create an object store on the transaction
var objectStore = transaction.objectStore("toDoList");
addData2(transaction, objectStore, newItem, 0, true);
};
function addData2(txn, store, records, i, commitT) {
try {
if (i < records.length) {
var rec = records[i];
var req = store.add(rec);
req.onsuccess = function(ev) {
i++;
console.log("Adding record " + i + " " + new Date());
addData2(txn, store, records, i, commitT);
return;
}
req.onerror = function(ev) {
console.log("Failed to add record." + " Error: " + ev.message);
}
} else if (i == records.length) {
console.log('Finished adding ' + records.length + " records");
}
} catch (e) {
console.log(e.message);
}
//console.log("#########")
};
function select() {
var transaction = db_handler.transaction('toDoList','readonly');
var store = transaction.objectStore('toDoList');
var index = store.index('tags');
var range = IDBKeyRange.bound(['101', 999],['101', 2001]);
var req = index.openCursor(range);
req.onsuccess = function(e){
var cursor = e.target.result;
if (cursor) {
if(cursor.value != null && cursor.value != undefined){
console.log(cursor.value);
}
cursor["continue"]();
}
}
}
</script>
</head>
<body>
<div id="selectButton">
<button onclick="select()">Select Data</button>
<input type="text" id="selectData" value="">
</div>
</body>
</html>
要点和概念解题陈述你有:
- 要求是从多个 属性 和范围限制搜索中搜索值。所以,你需要
- 一个complex/compound索引覆盖了你要搜索的楼盘(
IDBObjectStore.createIndex()
),这样你可以搜索多个 属性.
- A 基于范围的搜索,所以 -
IDBKeyRange.bound()
在上面的例子中,
- 复杂或复合索引是使用
objectStore.createIndex("tags",['user_id','create_data'], {unique:false});
创建的
- 范围是使用
var range = IDBKeyRange.bound(['101', 1000],['101', 2000]);
创建的
忠告:
var range = IDBKeyRange.bound(['101', 1000],['101', 2000]);
可以很好地满足您的需求,但请确定 var range = IDBKeyRange.bound(['101', 1000],['103', 2000]);
的结果
如果您使用的是 complex/compound 范围,那么它就像 101 到 103 OR 1000 到 2000 之间的范围。它不是 [=60 的 AND 而是 OR =] 您指定的范围。
尝试各种范围组合,您将了解 IDBKeyRange 的全部功能和限制。
我有一个包含多个索引的商店,我想查询。为了这个例子,假设我有一个带有 user_id 索引和 create_date 的消息存储,它是时间戳(并且假设我有索引 - user_id / create_date / user_id, create_date
我知道如何通过id查询用户:
var range = IDBKeyRange.only('123');
store.index('user_id').openCursor(range).onsuccess= function(e){....};
而且我知道如何按日期查询:
var range = IDBKeyRange.lowerBound(Date.now()-24 * 60 * 1000))
store.index('create_data').openCursor(range).onsuccess = function(e){....};
购买 我不知道如何一起查询。我知道我可以使用 JS 来解析这两个结果中的任何一个,但我想知道是否可以使用 IDB 来执行此操作。
编辑 - 我想做的伪查询是
user_id=123 AND create_date < (NOW() - 24 * 60 * 1000)
谢谢!
答案是使用IDBKeyRange.bound
:
var range = IDBKeyRange.bound(['123'],['123', Date.now()-10*1000]);
store.index('user_id,create_date').getCursor(range).onsuccess = function(e){...}
基本上,所有 IDBKeyRange 范围都可以使用 bound
范围来表示,因此通过使用多个值,我们可以创建我们想要的任何复合范围
下面是一个工作示例。
<!DOCTYPE html>
<html lang="en">
<head>
<title>Whosebug</title>
<script type="text/javascript" charset="utf-8">
var db_handler = null;
var dbDeleteRequest = window.indexedDB.deleteDatabase("toDoList");
dbDeleteRequest.onerror = function(event) {
console.log("Error while deleting database.", true);
};
dbDeleteRequest.onsuccess = function(event) {
// Let us open our database
var DBOpenRequest = window.indexedDB.open("toDoList", 5);
DBOpenRequest.onsuccess = function(event) {
console.log('<li>Database initialised.</li>');
// store the result of opening the database in the db variable. This is used a lot below
db_handler = DBOpenRequest.result;
// Run the addData() function to add the data to the database
addData();
};
DBOpenRequest.onupgradeneeded = function(event) {
console.log('<li>DBOpenRequest.onupgradeneeded</li>');
var db = event.target.result;
db.onerror = function(event) {
console.log('<li>Error loading database.</li>');
};
// Create an objectStore for this database //, { keyPath: "taskTitle" }); { autoIncrement : true }
var objectStore = db.createObjectStore("toDoList", { autoIncrement : true });
// define what data items the objectStore will contain
objectStore.createIndex("user_id", "user_id", { unique: false });
objectStore.createIndex("create_data", "create_data", { unique: false });
objectStore.createIndex("tags",['user_id','create_data'], {unique:false});
};
};
function addData() {
// Create a new object ready to insert into the IDB
var newItem = [];
newItem.push({ user_id: "101", create_data: (1000)});
newItem.push({ user_id: "102", create_data: (Date.now() - 18 * 60 * 1000)});
newItem.push({ user_id: "103", create_data: (Date.now() - 18 * 60 * 1000)});
newItem.push({ user_id: "101", create_data: (2000)});
newItem.push({ user_id: "101", create_data: (989)});
newItem.push({ user_id: "104", create_data: (Date.now() - 18 * 60 * 1000)});
console.log(newItem);
// open a read/write db transaction, ready for adding the data
var transaction = db_handler.transaction(["toDoList"], "readwrite");
// report on the success of opening the transaction
transaction.oncomplete = function(event) {
console.log('<li>Transaction completed: database modification finished.</li>' + new Date());
};
transaction.onerror = function(event) {
console.log('<li>Transaction not opened due to error. Duplicate items not allowed.</li>');
};
// create an object store on the transaction
var objectStore = transaction.objectStore("toDoList");
addData2(transaction, objectStore, newItem, 0, true);
};
function addData2(txn, store, records, i, commitT) {
try {
if (i < records.length) {
var rec = records[i];
var req = store.add(rec);
req.onsuccess = function(ev) {
i++;
console.log("Adding record " + i + " " + new Date());
addData2(txn, store, records, i, commitT);
return;
}
req.onerror = function(ev) {
console.log("Failed to add record." + " Error: " + ev.message);
}
} else if (i == records.length) {
console.log('Finished adding ' + records.length + " records");
}
} catch (e) {
console.log(e.message);
}
//console.log("#########")
};
function select() {
var transaction = db_handler.transaction('toDoList','readonly');
var store = transaction.objectStore('toDoList');
var index = store.index('tags');
var range = IDBKeyRange.bound(['101', 999],['101', 2001]);
var req = index.openCursor(range);
req.onsuccess = function(e){
var cursor = e.target.result;
if (cursor) {
if(cursor.value != null && cursor.value != undefined){
console.log(cursor.value);
}
cursor["continue"]();
}
}
}
</script>
</head>
<body>
<div id="selectButton">
<button onclick="select()">Select Data</button>
<input type="text" id="selectData" value="">
</div>
</body>
</html>
要点和概念解题陈述你有:
- 要求是从多个 属性 和范围限制搜索中搜索值。所以,你需要
- 一个complex/compound索引覆盖了你要搜索的楼盘(
IDBObjectStore.createIndex()
),这样你可以搜索多个 属性. - A 基于范围的搜索,所以 -
IDBKeyRange.bound()
- 一个complex/compound索引覆盖了你要搜索的楼盘(
在上面的例子中,
- 复杂或复合索引是使用
objectStore.createIndex("tags",['user_id','create_data'], {unique:false});
创建的
- 范围是使用
var range = IDBKeyRange.bound(['101', 1000],['101', 2000]);
创建的
忠告:
var range = IDBKeyRange.bound(['101', 1000],['101', 2000]);
可以很好地满足您的需求,但请确定 var range = IDBKeyRange.bound(['101', 1000],['103', 2000]);
如果您使用的是 complex/compound 范围,那么它就像 101 到 103 OR 1000 到 2000 之间的范围。它不是 [=60 的 AND 而是 OR =] 您指定的范围。
尝试各种范围组合,您将了解 IDBKeyRange 的全部功能和限制。