我想创建和使用两个IndexedDB索引,一个是简单的keyPath,另一个是复杂的keyPath。虽然在我尝试过的每一个浏览器中,创建都是成功的,但在大多数情况下,索引似乎没有得到正确的填充。
我使用的过程(问题末尾的独立测试用例)是:
{ keyPath: 'id', autoIncrement: true }。keyPath: 'id'和{ unique: false, multiEntry: false }创建的。第二个索引使用keyPath: ['id', 'name']和{ unique: false, multiEntry: false }创建。name属性。IDBIndex.count。预期是,IDBIndex.count的两个调用都将返回存储中存在的对象总数(19)。根据浏览器的不同,这种情况可能发生也可能不会发生:
如果我将索引的创建从{ unique: false, multiEntry: false }更改为{ unique: false },则每个浏览器的行为都保持不变。
如果我将复合索引的创建从['id', 'name']更改为(根据规格)等效id.name,则Safari将行为更改为simple: 19,complex: 0,其他则保持不变。
如果我将复杂索引的创建从'id'索引更改为['id'],则Safari仍然返回simple: 19,complex: 0,其他浏览器返回simple: 0,complex: 0。
我做错了什么?如何创建多属性索引?
(我目前正在使用下面的自带示例进行测试,由于使用了indexedDB,因此无法处理堆栈溢出)
var deleteRequest = indexedDB.deleteDatabase('test-db');
deleteRequest.onerror = deleteRequest.onblocked = deleteRequest.onsuccess = function () {
console.log('Database deleted', arguments);
var openRequest = indexedDB.open('test-db');
openRequest.onerror = function (errorEvent) { console.log('open error', errorEvent); };
openRequest.onblocked = function (blockedEvent) { console.log('open blocked', blockedEvent); };
openRequest.onupgradeneeded = function (upgradeEvent) {
console.log('Database opened');
var database = upgradeEvent.target.result;
var store = database.createObjectStore('sochrastic', { keyPath: 'id', autoIncrement: true });
store.createIndex('index_name', ['id', 'name'], { unique: false, multiEntry: false });
store.createIndex('index_id', 'id', { unique: false, multiEntry: false });
};
openRequest.onsuccess = function (successEvent) {
console.log('Indices created');
successEvent.target.result.close();
var openRequest = indexedDB.open('test-db');
openRequest.onerror = function (errorEvent) { console.log('open error', errorEvent); };
openRequest.onblocked = function (blockedEvent) { console.log('open blocked', blockedEvent); };
openRequest.onsuccess = function (upgradeEvent) {
console.log('Database opened');
var database = upgradeEvent.target.result;
var transaction = database.transaction('sochrastic', 'readwrite');
var store = transaction.objectStore('sochrastic');
store.add({ name: 'druk', badjorance: 'animal' });
store.add({ name: 'druk', badjorance: 'beast' });
store.add({ name: 'druk', badjorance: 'canal' });
store.add({ name: 'myke', badjorance: 'dice' });
store.add({ name: 'myke', badjorance: 'evergreen' });
store.add({ name: 'myke', badjorance: 'fake' });
store.add({ name: 'myke', badjorance: 'game' });
store.add({ name: 'grey', badjorance: 'honor' });
store.add({ name: 'grey', badjorance: 'incognito' });
store.add({ name: 'grey', badjorance: 'joke' });
store.add({ name: 'grey', badjorance: 'key' });
store.add({ name: 'grey', badjorance: 'lemon' });
store.add({ name: 'brady', badjorance: 'mast' });
store.add({ name: 'brady', badjorance: 'nothing' });
store.add({ name: 'brady', badjorance: 'opera' });
store.add({ name: 'brady', badjorance: 'pear' });
store.add({ name: 'brady', badjorance: 'quote' });
store.add({ name: 'brady', badjorance: 'rodent' });
store.add({ name: 'brady', badjorance: 'sunk' });
database.close();
var openRequest = indexedDB.open('test-db');
openRequest.onerror = function (errorEvent) { console.log('open error', errorEvent); };
openRequest.onblocked = function (blockedEvent) { console.log('open blocked', blockedEvent); };
openRequest.onsuccess = function (successEvent) {
console.log('Store filled');
var database = successEvent.target.result;
var transaction = database.transaction('sochrastic', 'readonly');
var store = transaction.objectStore('sochrastic');
var indexName = store.index('index_name');
var nameCountRequest = indexName.count();
nameCountRequest.onerror = function (errorEvent) { document.querySelector('#name-id-count').textContent = 'error'; console.log(errorEvent); };
nameCountRequest.onblocked = function (blockedEvent) { document.querySelector('#name-id-count').textContent = 'blocked'; console.log(blockedEvent); };
nameCountRequest.onsuccess = function (successEvent) { document.querySelector('#name-id-count').textContent = successEvent.target.result; console.log('name-id', successEvent.target.result); };
var indexId = store.index('index_id');
var idCountRequest = indexId.count();
idCountRequest.onerror = function (errorEvent) { document.querySelector('#id-count').textContent = 'error'; console.log(errorEvent); };
idCountRequest.onblocked = function (blockedEvent) { document.querySelector('#id-count').textContent = 'blocked'; console.log(blockedEvent); };
idCountRequest.onsuccess = function (successEvent) { document.querySelector('#id-count').textContent = successEvent.target.result; console.log('id', successEvent.target.result); };
}
}
}
}<!doctype html>
<html>
<head>
<meta charset="utf-8"/>
<title>IndexedDB Indices</title>
</head>
<body>
<p>['id', 'name'] index result: <span id="name-id-count"></span></p>
<p>['id'] index result: <span id="id-count"></span></p>
</body>
</html>
发布于 2017-04-01 04:40:15
IE和Edge根本不支持复杂索引,但您可以在其他浏览器中使用它们。
如果我将复杂索引的创建从“id”、“name”更改为(根据规范)等效的id.name,Safari将行为更改为simple: 19、complex: 0,其他则保持不变。
那可不是等价物。id.name在单个值(如{id: {name: 'value'}} )上创建索引,['id', 'name']在两个字段上创建一个复合索引,名称为{id: 1, name: 'value'}。
索引失败是因为您依赖于自动生成的主键id。如果您将id更改为badjorance,那么您的计数将如您所料,至少在火狐和Chrome中是如此。(顺便说一句,即使在你最初的例子中,我也没有看到任何区别,这两种浏览器都显示0。)
我猜有些浏览器在向对象添加主键之前会对keyPath进行评估,而其他浏览器则会在之后进行评估。至于哪种行为是正确的..。现在太晚了,我无法阅读规范,但除非规范不明确,否则您可能希望报告错误的浏览器中的错误。如果我是个投注的人,我猜Safari是错的。
https://stackoverflow.com/questions/43097337
复制相似问题