为什么这个 firestore 查询需要索引?

tok*_*ism 28 javascript firebase angularfire2 google-cloud-firestore

我有一个带有where()相等运算符的方法的查询,然后是一个orderBy()方法,但我无法弄清楚为什么它需要索引。where 方法检查对象(地图)中的值,order by 是一个数字。

文档说

如果您的过滤器具有范围比较(<、<=、>、>=),则您的第一个排序必须在同一字段上

所以我会认为平等过滤器会很好。

这是我的查询代码:

this.afs.collection('posts').ref
.where('tags.' + this.courseID,'==',true)
.orderBy("votes")
.limit(5)
.get().then(snap => {
  snap.forEach(doc => {
    console.log(doc.data());
  });
});
Run Code Online (Sandbox Code Playgroud)

这是数据库结构的示例 在此处输入图片说明

Ale*_*amo 56

为什么这个 Firestore 查询需要索引?

您可能已经注意到,Cloud Firestore 中的查询速度非常快,这是因为 Firestore 会自动为您文档中的任何字段创建索引。因此,当您简单地使用范围比较进行过滤时,Firestore 会自动创建所需的索引。如果您还尝试对结果进行排序,则需要另一个索引。这种索引不是自动创建的。你应该自己创建它。这可以通过在Firebase 控制台中手动创建来完成,或者您会在日志中找到一条消息,听起来像这样:

FAILED_PRECONDITION: The query requires an index. You can create it here: ...
Run Code Online (Sandbox Code Playgroud)

您只需单击该链接或将 URL 复制并粘贴到 Web 浏览器中,就会自动创建您的索引。

因此 Firestore 需要一个索引,以便您可以进行非常快速的查询。

  • @Devashish 创建索引后,无需执行任何操作。它将适用于任意数量的文档。 (2认同)

bso*_*sod 8

索引只是一个数据库清单或什么位置的记录。每个索引都是特定事物的特定清单 - 例如,propertyX集合中存在多少个字段以及它们的值是什么,已排序(对它们进行排序这一事实至关重要)。

如果此清单不存在,要查询文档 where propertyXis someValue,机器必须遍历整个集合以确定 (1) 哪些文档包含propertyX和 (2) 哪些文档包含propertyX等于someValue。通过保留查询属性的清单(或索引),当对 执行查询时propertyX,机器可以直接进入propertyX索引并收集所有相等的文档的位置,someValue然后从集合中获取这些文档并返回它们。机器不仅不需要接触集合来知道文档在哪里,而且它甚至不需要遍历整个索引,因为它总是有序的。

索引是集合大小对 Firestore 查询性能没有影响的原因,也是为什么我们只需要索引曾经查询过的属性的原因。