IndexedDB - 范围
IndexedDB:使用 IDBKeyRange 查询数据范围
Section titled “IndexedDB:使用 IDBKeyRange 查询数据范围”除了获取单个记录之外,你还需要查询特定范围内的数据。例如,查找今天收到的所有电子邮件,或价格在 50 美元到 100 美元之间的所有产品。IndexedDB 正为此目的提供了 IDBKeyRange 对象。
一个 IDBKeyRange 定义了键的一个连续范围。你可以将其与 getAll()、openCursor() 或 count() 等方法一起使用,以从对象存储或索引中过滤结果。
创建键范围的方法
Section titled “创建键范围的方法”IDBKeyRange 对象有几个静态方法来定义不同类型的范围:
| 方法 | 描述 | 示例(范围) |
|---|---|---|
| IDBKeyRange.lowerBound(lower, [open]) | 匹配所有大于或等于 lower 的键。如果 open 为 true,则匹配严格大于 lower 的键。 | ≥ a or > a |
| IDBKeyRange.upperBound(upper, [open]) | 匹配所有小于或等于 upper 的键。如果 open 为 true,则匹配严格小于 upper 的键。 | ≤ b or < b |
| IDBKeyRange.bound(lower, upper, [lowerOpen], [upperOpen]) | 匹配所有在 lower 和 upper 之间的键。open 标志可用于排除边界。 | ≥ a && ≤ b |
| IDBKeyRange.only(value) | 只匹配精确等于 value 的键。 | = c |
以下是如何将这些范围应用于具有 price 索引的 products 存储的一些示例。
// 查找价格 >= 100 的产品const range1 = IDBKeyRange.lowerBound(100);const expensiveProducts = await db.getAllFromIndex('products', 'priceIdx', range1);
// 查找价格 < 20 的产品(不包含 20)const range2 = IDBKeyRange.upperBound(20, true);const cheapProducts = await db.getAllFromIndex('products', 'priceIdx', range2);
// 查找价格在 50 到 150 之间的产品(包含 50 和 150)const range3 = IDBKeyRange.bound(50, 150);const midRangeProducts = await db.getAllFromIndex('products', 'priceIdx', range3);
// 查找所有价格精确为 99.99 的产品const range4 = IDBKeyRange.only(99.99);const specificPriceProducts = await db.getAllFromIndex('products', 'priceIdx', range4);完整示例:按日期范围查询
Section titled “完整示例:按日期范围查询”一个常见的用例是根据日期范围获取记录。此示例创建一个 logs 存储,添加带有时间戳的条目,然后查询在过去一小时内创建的日志。
<!DOCTYPE html><html lang="en"><head> <title>IndexedDB 范围查询示例</title></head><body> <h1>检查控制台输出</h1> <script type="module"> import { openDB } from 'https://cdn.jsdelivr.net/npm/idb@7/build/index.js';
async function runDemo() { const db = await openDB('appLogsDB', 1, { upgrade(db) { const store = db.createObjectStore('logs', { autoIncrement: true }); store.createIndex('timestampIdx', 'timestamp'); }, });
const twoHoursAgo = new Date(); twoHoursAgo.setHours(twoHoursAgo.getHours() - 2); const thirtyMinsAgo = new Date(); thirtyMinsAgo.setMinutes(thirtyMinsAgo.getMinutes() - 30);
// 添加一些示例数据 const tx = db.transaction('logs', 'readwrite'); await Promise.all([ tx.store.add({ message: 'User logged in', timestamp: new Date() }), tx.store.add({ message: 'Data fetched from API', timestamp: thirtyMinsAgo }), tx.store.add({ message: 'Old session cleared', timestamp: twoHoursAgo }), ]); await tx.done;
// 查询过去一小时的日志 const oneHourAgo = new Date(); oneHourAgo.setHours(oneHourAgo.getHours() - 1);
const range = IDBKeyRange.lowerBound(oneHourAgo); const recentLogs = await db.getAllFromIndex('logs', 'timestampIdx', range);
console.log('Logs from the last hour:'); console.table(recentLogs); }
runDemo().catch(console.error); </script></body></html>控制台将显示一个表格,其中包含过去一小时内的两条日志条目(‘User logged in’ 和 ‘Data fetched from API’),不包括两小时前的条目。