idbkeyrange 是 indexeddb 中定义键范围的工具,用于配合 opencursor 或 getall 精准查询区间数据,支持 only、bound、lowerbound、upperbound 四种构造方式,需注意键类型、索引依赖和字符串比较规则。

IDBKeyRange 是 IndexedDB 中用于定义键范围的工具,能帮你精准查出落在某区间内的记录,比如“2023年1月到12月的订单”或“用户ID在 100 到 200 之间的数据”。它不直接执行查询,而是配合 objectStore.openCursor() 或 objectStore.getAll() 使用,告诉数据库“只处理这个范围里的键”。
创建常见类型的 IDBKeyRange
根据匹配逻辑不同,有四种基础构造方式:
-
单点匹配:
IDBKeyRange.only(key)—— 只匹配完全相等的键,例如IDBKeyRange.only(123) -
左闭右闭区间:
IDBKeyRange.bound(lower, upper, lowerOpen = false, upperOpen = false)—— 默认包含端点,如IDBKeyRange.bound(10, 20)匹配 10、11…20 -
左开右闭/左闭右开:通过第三个、第四个布尔参数控制开闭,例如
IDBKeyRange.bound(10, 20, true, false)匹配 11 到 20(不含 10) -
单向范围:
IDBKeyRange.lowerBound(10)(≥10)、IDBKeyRange.upperBound(100)(≤100),可加true参数表示不包含端点
配合游标遍历区间数据
这是最常用也最灵活的方式,适合大数据量或需要逐条处理的场景:
const transaction = db.transaction(['orders'], 'readonly');
const store = transaction.objectStore('orders');
const range = IDBKeyRange.bound(new Date('2023-01-01'), new Date('2023-12-31'));
store.openCursor(range).onsuccess = function(event) {
const cursor = event.target.result;
if (cursor) {
console.log('订单ID:', cursor.key, '内容:', cursor.value);
cursor.continue(); // 继续下一条
}
};
注意:游标默认按主键升序遍历;若索引字段是日期或数字,确保该字段已建索引且作为游标范围的依据(例如用 index.openCursor(range))。
一次性获取全部匹配项
适合结果数量可控(一般几百条以内),代码更简洁:
const index = store.index('dateIndex'); // 假设已为 date 字段建了索引
const range = IDBKeyRange.bound(startDate, endDate);
index.getAll(range).onsuccess = function(event) {
const results = event.target.result; // 数组,含所有匹配记录的 value
console.log(results);
};
⚠️ 注意:getAll() 返回的是 value 数组,不带 key;如果需要 key,改用 getAllKeys(range),或用游标。
实际使用要点提醒
- 键类型必须可比较:数字、Date、字符串、Array 都行,但不能是对象或函数;Date 类型要确保存入时是毫秒时间戳或标准 Date 实例(避免字符串格式如 "2023-01-01" 直接比较)
- 范围匹配依赖索引顺序:若按非主键字段查,必须用
objectStore.index('xxx').openCursor(range),不能直接在 store 上用 - 空范围会返回空结果:比如
IDBKeyRange.bound(100, 50)无效,浏览器不会报错但不匹配任何数据 - 字符串范围需注意字典序:'apple' 到 'banana' 可以,但 '10'
用对 IDBKeyRange,查区间数据就变得清晰可控。关键是先理清查的是主键还是索引字段,再选对构造方式和查询方法。










