Flutter中Cloud Firestore带whereNotIn的复合查询搭配游标范围查询失效问题
问题根因
- Firestore的游标
startAt/endAt传入的参数顺序、数量必须和查询中orderBy的字段完全对应,游标是按排序字段的优先级依次匹配,而非仅匹配最后一个排序字段。 - 你的复合查询排序规则为
orderBy('user.id').orderBy('user.age'),包含两个排序字段,但是你只给游标传入了[28]/[31]一个参数,系统会默认把28当做第一个排序字段user.id的匹配阈值,自然没有符合条件的记录返回。这一问题和whereNotIn本身无关,你的猜测不成立。
可用解决方案
方案1:调整游标参数匹配排序规则
如果需要保留现有排序逻辑,且坚持用游标做范围控制,需要传入两个参数分别对应两个排序字段:
// 第一个参数填你需要的user.id起始阈值,第二个对应age起始阈值 collection.where('user.id', whereNotIn: blackList).orderBy('user.id').orderBy('user.age').startAt([blackList.last + 1, 28]).endAt([999999, 31]);
该方案仅适合需要分页的场景,用作字段过滤的话灵活度极低。
方案2:用where条件做age范围过滤(推荐)
游标设计初衷是分页定位,而非字段范围过滤,你可以直接新增age的范围过滤条件,写法更简洁也符合Firestore的查询规范:
collection .where('user.id', whereNotIn: blackList) .where('user.age', isGreaterThanOrEqualTo: 28) .where('user.age', isLessThanOrEqualTo: 31) .orderBy('user.id') .orderBy('user.age');
该写法可以正常返回你预期的id1 age29的记录。
补充说明
你使用的Flutter2.4预览版不存在Firestore游标相关的兼容性问题,本次问题完全是查询规则使用不当导致。
内容的提问来源于stack exchange,提问作者E.K.
相关产品推荐
相关产品推荐

