我有一个商店,我想查询多个索引。为了示例,我们假设我有一个带有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解析2中的任何一个的结果,但我想知道是否可以使用IDB来做到这一点。
编辑 - 我想要做的伪查询是
user_id=123 AND create_date < (NOW() - 24 * 60 * 1000)
谢谢!
答案 0 :(得分:0)
答案是使用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
范围表示,因此通过使用多个值,我们可以创建任何我们想要的复合范围
答案 1 :(得分:0)
下面的工作示例。
<!DOCTYPE html>
<html lang="en">
<head>
<title>Stackoverflow</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>
关键点和概念,以解决您的问题陈述:
IDBObjectStore.createIndex()
),以便您可以搜索多个媒体资源。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]);
如果您使用的是复数/化合物范围,那么它的范围介于101到103 OR 1000到2000之间。它不是AND而是您指定的复数/化合物范围的OR。
尝试各种范围组合,您将了解IDBKeyRange的全部功能和限制。