如何在Firebase Firestore中使用多个orderBy查询实现排序?
解决方案
Firestore有两个不可绕过的底层查询限制:
- 单次查询中,只能对同一个字段使用不等式操作符(
!=、>、<、>=、<=) - 用到不等式的字段,必须作为
orderBy的第一个排序字段
你之前的写法报错的核心原因,要么是违反了上述第一条(同时对sellingPrice、totalUnit两个字段用不等式),要么违反了第二条(不等式字段和第一个排序字段不匹配)。
最优方案:改造数据结构(推荐)
给商品文档新增布尔类型的hasStock冗余字段,库存变更时自动同步值:当库存count>0时设为true,count=0时设为false。
因为等值查询(isEqualTo)不受上述排序规则限制,改造后查询代码如下:
DBRef.collection("col") .where("hasStock", isEqualTo: true) .orderBy("price") .get();
该方案性能最好,完全匹配Firestore索引规则,无需额外处理,适合所有业务场景。
备选方案:客户端二次排序
如果暂时无法修改数据结构,可以先按Firestore规则查询到结果后,在客户端重新按price排序:
// 先按Firestore要求的规则查询 final querySnapshot = await DBRef.collection("col") .where("count", isGreaterThan: 0) // 此处用isGreaterThan替代isNotEqual,查询性能更高,结果一致 .orderBy("count") .orderBy("price") .get(); // 客户端对结果重新按price排序 final sortedResult = querySnapshot.docs..sort((a, b) => a.data()['price'].compareTo(b.data()['price']) ); // 若需要倒序排序,替换为b.data()['price'].compareTo(a.data()['price'])即可
该方案适合单次查询返回数据量较小的场景,数据量过大会产生客户端性能损耗。
变通写法报错原因
你之前尝试的多字段不等式查询本身不符合Firestore规则,同时对sellingPrice、totalUnit两个不同字段使用isGreaterThan这类不等式条件,无论怎么调整orderBy顺序都会报错,无兼容写法。
内容的提问来源于stack exchange,提问作者Mayur Agarwal
相关产品推荐
相关产品推荐

