如何处理 firebase 中多个 where 查询的索引?
How to deal with indexes of multiple where query in firebase?
在我的 flutter 应用中。我必须使用多个过滤器从 firebase 获取数据。
我做了如下操作。它有效,但问题是某些过滤器为空,因此我需要在 firebase 查询中跳过它,因此,即使我只有 2 个字段(姓名、年龄),我也必须创建 3 个索引来支持我的查询。第一个索引用于:姓名,第二个索引用于:年龄,第三个索引用于:姓名和年龄。
Future<List<Transac>> getTrans(TransFilter filter, Transac? lastTrans) async {
const limit = 10;
var result =
_collection.orderBy(filter.orderBy, descending: true).limit(limit);
if (filter.directionId != null) {
result = result.where(directionIdKey, isEqualTo: filter.directionId);
}
if (filter.flag != null) {
result = result.where(Transac.flagKey, isEqualTo: filter.flag);
}
if (filter.officeId != null) {
result = result.where(officeIdKey, isEqualTo: filter.officeId);
}
if (lastTrans != null) {
result = result.startAfter([lastTrans.createdAt.millisecondsSinceEpoch]);
}
final _result = await result.get().then(
(value) => value.docs.map((e) => Transac.fromSnapshot(e)).toList());
return _result;
}
我已经尝试了下面的方法,因为我认为我只需要一次创建所有索引,但它会抛出一个错误,因为我不能在第一个 orderby 中未使用的字段上使用 isNotEqualTo。
Future<List<Transac>> getTrans(TransFilter filter, Transac? lastTrans) async {
const limit = 10;
var result =
_collection.orderBy(filter.orderBy, descending: true).limit(limit);
if (filter.directionId != null) {
result = result.where(directionIdKey, isEqualTo: filter.directionId);
}else {
result = result.where(directionIdKey, isNotEqualTo: '');
}
if (filter.officeId != null) {
result = result.where(officeIdKey, isEqualTo: filter.officeId);
}else {
result = result.where(officeIdKey, isNotEqualTo: '');
}
if (lastTrans != null) {
result = result.startAfter([lastTrans.createdAt.millisecondsSinceEpoch]);
}
final _result = await result.get().then(
(value) => value.docs.map((e) => Transac.fromSnapshot(e)).toList());
return _result;
}
有什么解决办法或建议吗?非常感谢您的帮助,谢谢
您有 3 个参数要按 directionIdKey
、Transac.flagKey
、officeIdKey
过滤。您要排序:filter.orderBy
.
我相信这些参数包含字段名称。
我们需要一个将出现在所有查询中的字段。我们使用您的 orderBy 字段。
所以创建3个复合索引。
- filter.orderBy 和 directionIdKey ASC
- filter.orderBy 和 Transac.flagKey ASC
- filter.orderBy 和 officeIdKey ASC
这应该可以处理您的查询。
在我的 flutter 应用中。我必须使用多个过滤器从 firebase 获取数据。
我做了如下操作。它有效,但问题是某些过滤器为空,因此我需要在 firebase 查询中跳过它,因此,即使我只有 2 个字段(姓名、年龄),我也必须创建 3 个索引来支持我的查询。第一个索引用于:姓名,第二个索引用于:年龄,第三个索引用于:姓名和年龄。
Future<List<Transac>> getTrans(TransFilter filter, Transac? lastTrans) async {
const limit = 10;
var result =
_collection.orderBy(filter.orderBy, descending: true).limit(limit);
if (filter.directionId != null) {
result = result.where(directionIdKey, isEqualTo: filter.directionId);
}
if (filter.flag != null) {
result = result.where(Transac.flagKey, isEqualTo: filter.flag);
}
if (filter.officeId != null) {
result = result.where(officeIdKey, isEqualTo: filter.officeId);
}
if (lastTrans != null) {
result = result.startAfter([lastTrans.createdAt.millisecondsSinceEpoch]);
}
final _result = await result.get().then(
(value) => value.docs.map((e) => Transac.fromSnapshot(e)).toList());
return _result;
}
我已经尝试了下面的方法,因为我认为我只需要一次创建所有索引,但它会抛出一个错误,因为我不能在第一个 orderby 中未使用的字段上使用 isNotEqualTo。
Future<List<Transac>> getTrans(TransFilter filter, Transac? lastTrans) async {
const limit = 10;
var result =
_collection.orderBy(filter.orderBy, descending: true).limit(limit);
if (filter.directionId != null) {
result = result.where(directionIdKey, isEqualTo: filter.directionId);
}else {
result = result.where(directionIdKey, isNotEqualTo: '');
}
if (filter.officeId != null) {
result = result.where(officeIdKey, isEqualTo: filter.officeId);
}else {
result = result.where(officeIdKey, isNotEqualTo: '');
}
if (lastTrans != null) {
result = result.startAfter([lastTrans.createdAt.millisecondsSinceEpoch]);
}
final _result = await result.get().then(
(value) => value.docs.map((e) => Transac.fromSnapshot(e)).toList());
return _result;
}
有什么解决办法或建议吗?非常感谢您的帮助,谢谢
您有 3 个参数要按 directionIdKey
、Transac.flagKey
、officeIdKey
过滤。您要排序:filter.orderBy
.
我相信这些参数包含字段名称。
我们需要一个将出现在所有查询中的字段。我们使用您的 orderBy 字段。 所以创建3个复合索引。
- filter.orderBy 和 directionIdKey ASC
- filter.orderBy 和 Transac.flagKey ASC
- filter.orderBy 和 officeIdKey ASC
这应该可以处理您的查询。