Firestore 字段在查询中使用 orderBy 所需的索引

时间:2021-07-03 16:20:05

标签: javascript google-cloud-firestore

我正在构建一个简单的查询,其中包括最后的排序。

但 firestore 要求我创建结合查询字段和 orderBy 字段的索引。并且将为此创建许多索引,将订单字段与其余字段(甚至字段组合)结合起来。

我有 4 个字段来过滤结果,需要按另一个字段排序,我必须为不同的组合创建 24 个索引,包括升序和降序。如果我有几十个字段,这样吗?我想我将不得不创建数百个索引。

那么,即使对于 ASCDESC 两个方向,继续并创建所有这些众多的字段组合索引与按字段排序的索引是否是一个好习惯?如果我继续这样做会产生问题吗?或者哪种模式适合这种简单的任务方式来执行此操作?

我的查询是

var query = ref.collection("data/devices");

if (params.region) query = query.where("region", "==", params.region);
if (params.color) query = query.where("color", "==", params.color);
query = query.orderBy("price", "ASC ");

在我的测试中,只有 params.color 未包含在内,因为它未定义。所以查询只有 .where("region") 和 orderBy price

它产生了这个错误 Error: 9 FAILED_PRECONDITION: The query requires an index. You can create it here: [Link to create the index]

1 个答案:

答案 0 :(得分:2)

要处理您显示的查询:

var query = ref.collection("data/devices");

if (params.region) query = query.where("region", "==", params.region);
if (params.color) query = query.where("color", "==", params.color);
query = query.orderBy("price", "ASC");

您需要创建 2 个复合索引:

  • 区域 ASC,价格 ASC
  • 颜色 ASC,价格 ASC

这 2 个单独的索引将被合并,并且能够处理您需要的组合,即使同时使用 region 和/或 color。例如:

db.collection('whatever')
  .where('region', '==', 'A')
  .where('color', '==', 'B')
  .where('prop3', '==', 'C')
  .where('prop4', '==', 'D')
  .orderBy('price', 'ASC');

如果该查询正是您将始终使用的查询,您可以创建一个包含 5 个字段的复合索引。但是,如果“where”子句是可选的,那么您需要创建 4 个不同的复合索引:

  • 区域 ASC,价格 ASC
  • 颜色 ASC,价格 ASC
  • prop3 ASC,价格 ASC
  • prop4 ASC,价格 ASC

您还可以享受不同组合的好处,例如:

.where('region', '==', 'A').where('prop4', '==', 'D').orderBy('price', 'ASC');

例如。

这称为索引合并,并且很好地解释了here

编辑: 请注意:

  • 索引合并仅适用于相等比较 (.where('x', '==', 5)) 而不适用于范围比较 (.where('x', '<', 5))。
  • 如果您想按 price,DESC 而不是 ASC 排序,您必须按照 here 的说明创建一组不同的索引。