Quasar/Electron应用中Dexie/IndexedDB复合键查询优化:获取特定事件下唯一犬只的完整记录
嘿,这个问题我熟!你其实完全可以直接在Dexie层面完成特定事件下获取唯一犬只的完整记录,不需要先拉所有数据再前端过滤,效率会高很多。
你的复合索引[fk_event+fk_dog]已经搭建好了,这是关键!我们可以直接利用这个索引做范围查询,再结合去重方法拿到完整记录,一步到位。
最优实现方案
这里有两种等价的写法,都能高效满足你的需求:
写法1:用startsWith匹配事件ID前缀
这种写法最直观,利用复合索引的前缀特性快速定位目标事件的所有记录:
// 获取当前事件下,每个唯一犬只的完整记录(默认返回索引顺序的第一条) const uniqueRuns = await myDB.runTable .orderBy('[fk_event+fk_dog]') .startsWith([this.currentEventID]) // 只筛选当前事件的记录 .distinct(record => record.fk_dog) // 按犬只ID去重 .toArray(); this.enteredRuns = uniqueRuns;
如果需要每个犬只在该事件下的最新记录,只需要加个reverse()倒序,这样最新的记录会被优先选中:
const uniqueRuns = await myDB.runTable .orderBy('[fk_event+fk_dog]') .startsWith([this.currentEventID]) .reverse() // 倒序排列,最新记录在前 .distinct(record => record.fk_dog) .toArray(); this.enteredRuns = uniqueRuns;
写法2:用between做精确范围查询
如果你更喜欢明确的范围限定,可以用Dexie.minKey和Dexie.maxKey来覆盖该事件下的所有犬只ID:
import Dexie from 'dexie'; const uniqueRuns = await myDB.runTable .where('[fk_event+fk_dog]') .between( [this.currentEventID, Dexie.minKey], [this.currentEventID, Dexie.maxKey] ) .distinct(record => record.fk_dog) .toArray(); this.enteredRuns = uniqueRuns;
为什么这个方案更好?
- 数据库层面过滤:直接利用索引筛选当前事件的记录,不需要拉取全表数据,减少了IO和内存占用
- 一步到位拿完整记录:不再需要先拿复合键再二次查询,或者前端循环构建数组
- 高效利用索引:复合索引让查询和去重都非常快,数据量越大,优势越明显
之前你尝试组合唯一键函数和where子句没成功,大概率是写法问题——现在这个写法完美结合了范围过滤和去重,直接返回你需要的完整记录。
内容的提问来源于stack exchange,提问作者Cynthia
相关产品推荐
相关产品推荐

