IndexedDB 过滤依赖索引定位、游标遍历与 JavaScript 条件判断三层协同:索引决定高效查询能力(单字段支持范围、复合索引需前缀匹配、多值索引支持数组包含),游标按需取数并支持分页,JS 执行剩余逻辑,复杂条件(OR/IN/模糊匹配)需应用层封装。

IndexedDB 本身不提供 SQL 风格的 WHERE 过滤器,它的“过滤”是靠索引 + 游标 + JavaScript 判断三者协同完成的。核心逻辑不是在数据库层做条件合并,而是在数据访问路径上分层收窄:先用索引快速定位候选集,再用游标遍历,最后在内存中对每条记录执行 JS 条件判断。
索引决定能“快查什么”
索引是过滤能力的起点。没有对应索引的字段,就无法高效参与初始筛选。
- 单字段索引(如 age)支持范围查询:用
IDBKeyRange.bound(25, 35)获取 age 在 25–35 之间的所有记录游标 - 复合索引(如 ["city", "active"])支持前缀匹配:可查
city === "杭州",或city === "杭州" && active === true;但不能跳过 city 直接查active === true - 多值索引(
multiEntry: true)适用于数组字段:比如tags: ["work", "urgent"],设为 multiEntry 后,每项都会生成独立索引条目,支持tags includes "work"类查询
游标负责“按需取数”
游标不是一次性加载全部结果,而是按顺序逐条推进,配合范围参数可精准控制起止位置。
- 在索引上打开游标(
index.openCursor(range)),比在对象仓库上打开更高效——它只遍历索引键,不读取完整记录 - 使用
cursor.continue(key)可跳转到指定键继续,适合分页或断点续查 - 对大数据量,建议用
requestIdleCallback或setTimeout分批处理游标,避免阻塞渲染主线程
JavaScript 执行最终“条件拍板”
当索引无法完全覆盖所有条件时,剩余逻辑必须由 JS 完成。这不是妥协,而是 IndexedDB 的设计哲学:把复杂逻辑交给应用层,保持底层轻量。
- 例如查
city IN ["北京","上海"] && age > 28 && active === true:先用by_city索引分别获取两个城市的游标,合并后逐条判断 age 和 active - 注意避免在游标回调里做耗时操作(如正则匹配、深比较),可提前序列化或缓存中间结果
- 若频繁执行同类组合条件,考虑预建更精准的复合索引(如
["city", "age", "active"]),把尽可能多的条件“固化”进索引结构
高级过滤需要额外封装
原生 API 不直接支持 OR、IN、模糊匹配、聚合等,需自行构建抽象层。
- OR 条件(如 status = "draft" OR status = "pending"):分别用索引查两组结果,用 Set 去重主键后合并
- 全文关键词匹配:可借助
textEncoder+ 前缀索引模拟,或引入轻量库如 idb(封装了 Promise 和高级查询辅助) - 排序与分页:优先依赖索引顺序输出;若需按非索引字段排序,只能先收集全部匹配项再
Array.sort(),注意内存占用

















