idbkeyrange 是 indexeddb 中用于定义键取值范围的只读对象,通过 lowerbound、upperbound、bound 和 only 四个静态方法创建,支持 ≥、≤、介于、等于等条件查询,必须配合游标或 get/getall 使用,依赖索引有序性,不可 new 实例化。

IndexedDB 中使用 IDBKeyRange 是实现高效范围查询的核心方式,它能让你按主键或索引键精确指定“大于、小于、介于、包含”等条件,避免全表扫描。
什么是 IDBKeyRange?
IDBKeyRange 是一个只读对象,用于定义键的取值范围,本身不存储数据,仅作为游标(cursor)或 get/getAll 等操作的查询条件。它必须通过静态方法创建,不能用 new 实例化。
常用创建方法有四个:
-
IDBKeyRange.lowerBound(lower, open = false):匹配 ≥(或 >,若open为true)lower的键 -
IDBKeyRange.upperBound(upper, open = false):匹配 ≤(或,若 <code>open为true)upper的键 -
IDBKeyRange.bound(lower, upper, lowerOpen = false, upperOpen = false):同时限定上下界,例如IDBKeyRange.bound(10, 20, false, true)表示10 ≤ key -
IDBKeyRange.only(value):精确匹配单个键(常用于get())
在 objectStore 上按主键范围查询
假设你有一个用户数据库,主键是自增数字 id,想查 id 在 100–199 之间的所有用户:
const transaction = db.transaction('users', 'readonly');
const store = transaction.objectStore('users');
const range = IDBKeyRange.bound(100, 199);
store.getAll(range).onsuccess = function(e) {
console.log('匹配的用户:', e.target.result); // 返回数组
};
注意:getAll() 一次性读取全部匹配项,适合结果量小;量大时建议用游标分页遍历。
在 index 上按非主键字段范围检索
如果想按时间戳 createdAt 查某天的数据,需先确保该字段建了索引:
// 创建索引(升级数据库时)
if (oldVersion
<p>然后查询 2024-01-01 到 2024-01-02 的日志:</p>
<pre class="brush:php;toolbar:false;">const index = store.index('byCreatedAt');
const start = new Date('2024-01-01').getTime();
const end = new Date('2024-01-02').getTime();
const range = IDBKeyRange.bound(start, end);
index.getAll(range).onsuccess = e => {
console.log('当日日志:', e.target.result);
};
⚠️ 关键点:索引字段值必须是可排序类型(如 number、string、Date),且范围查询依赖索引的有序性,否则无法生效。
游标遍历 + 范围过滤(内存友好)
当数据量大、不想一次性加载时,用 openCursor() 配合 IDBKeyRange 更稳妥:
const range = IDBKeyRange.lowerBound(500);
store.openCursor(range).onsuccess = function(e) {
const cursor = e.target.result;
if (cursor) {
console.log('ID:', cursor.key, 'Data:', cursor.value);
cursor.continue(); // 继续下一条
}
};
你还可以在游标中加业务逻辑判断,比如跳过某些状态的记录,或手动中断(cursor.advance(n) 或 break)。
掌握 IDBKeyRange 就掌握了 IndexedDB 查询的“精准定位”能力,配合 objectStore 主键和 index 字段,就能覆盖绝大多数区间检索场景。
Java免费学习笔记:立即使用
解锁 Java 大师之旅:从入门到精通的终极指南











