管理 Cloud Firestore 中的索引

为保证查询性能,Cloud Firestore 要求每个查询都要有索引。它会自动为您创建最基本的查询所需的索引。在您使用和测试应用的过程中,Cloud Firestore 会生成错误消息,帮助您创建您的应用所需的额外索引。本页面介绍如何管理单字段索引和复合索引。

通过错误消息创建缺少的索引

如果您尝试使用未映射到现有索引的范围子句进行复合查询,则会收到错误。错误消息中包含一个直接链接,用于在 Firebase 控制台中创建缺失的索引。

通过生成的链接转到 Firebase 控制台,查看自动填充的信息,然后点击创建

角色与权限

要在 Cloud Firestore 中创建索引,您必须分配有以下角色之一:

  • roles/datastore.owner
  • roles/datastore.indexAdmin
  • roles/editor
  • roles/owner

如果您定义了自定义角色,则必须为其分配以下所有权限才能创建索引:

  • datastore.indexes.create
  • datastore.indexes.delete
  • datastore.indexes.get
  • datastore.indexes.list
  • datastore.indexes.update

使用 Firebase 控制台

如需在 Firebase 控制台中手动创建新的索引,请执行以下操作:

Firebase 控制台中的 Firestore 索引编制界面的图片

  1. 前往 Firebase 控制台Cloud Firestore 部分。
  2. 进入索引标签页,然后点击添加索引
  3. 输入集合名称,并设置索引排序时将依据的字段。
  4. 点击创建

索引字段必须遵循对字段路径的限制条件

索引可能需要几分钟才能构建完毕,具体取决于查询的大小。创建索引后,您可以在“复合索引”部分中查看这些索引及其状态。如果它们仍在构建中,则 Firebase 控制台会包括一个表示正在构建的状态栏。

移除索引

如需删除索引,请执行以下操作:

  1. 前往 Firebase 控制台Cloud Firestore 部分。
  2. 点击索引标签页。
  3. 将鼠标悬停在要删除的索引上,然后从上下文菜单中选择删除
  4. 点击警告中的删除,确认您要删除该索引。

使用 Firebase CLI

您还可以使用 Firebase CLI 部署索引。如需开始使用,请在您的项目目录中运行 firebase init firestore。在设置过程中,Firebase CLI 会以正确的格式生成一个包含默认索引的 JSON 文件。修改该文件以添加更多索引,并使用 firebase deploy 命令部署该文件。

如需仅部署 Cloud Firestore 索引和规则,请添加 --only firestore 标志。

如果您使用 Firebase 控制台对索引进行了修改,请务必同时更新本地索引文件。请参阅 JSON 索引定义参考文档

使用 Terraform

在数据库中创建索引

Cloud Firestore 数据库可以包含一个单字段索引或复合索引。您可以修改 Terraform 配置文件,为数据库创建索引。

单字段索引

以下示例 Terraform 配置文件会在 chatrooms 集合的 name 字段中创建单字段索引:

firestore.tf

resource "random_id" "variable"{
  byte_length = 8
}

resource "google_firestore_field" "single-index" {
  project = "project-id"
  database = "database-id"
  collection = "chatrooms_${random_id.variable.hex}"
  field = "name"

  index_config {
    indexes {
        order = "ASCENDING"
        query_scope = "COLLECTION_GROUP"
    }
    indexes {
        array_config = "CONTAINS"
    }
  }

  ttl_config {}
}
  • project-id 替换为项目 ID。项目 ID 不得重复。
  • database-id 替换为您的数据库 ID。

复合索引

以下示例 Terraform 配置文件会为 chatrooms 集合中的 name 字段和 description 字段创建一个复合索引:

firestore.tf

resource "google_firestore_index" "composite-index" {
  project = "project-id"
  database = "database-id"

  collection = "chatrooms"

  fields {
    field_path = "name"
    order      = "ASCENDING"
  }

  fields {
    field_path = "description"
    order      = "DESCENDING"
  }

}
  • project-id 替换为项目 ID。项目 ID 不得重复。
  • database-id 替换为您的数据库 ID。

索引构建时间

为了构建索引,Firestore 必须设置索引,然后使用现有数据回填索引。索引构建时间是设置时间和回填时间的总和:

  • 设置索引需要几分钟时间。索引的最短构建时间为几分钟,即使空数据库也是如此。

  • 回填时间取决于属于新索引的现有数据的数量。与索引定义匹配的字段值越多,回填索引所需的时间就越长。

索引构建是长时间运行的操作。

在您启动索引构建后,Cloud Firestore 会为操作分配一个唯一名称。操作名称的前缀为 projects/[PROJECT_ID]/databases/(default)/operations/,例如:

projects/project-id/databases/(default)/operations/ASA1MTAwNDQxNAgadGx1YWZlZAcSeWx0aGdpbi1zYm9qLW5pbWRhEgopEg

不过,您可以在指定 describe 命令的操作名称时省略前缀。

列出所有长时间运行的操作

如需列出长时间运行的操作,请使用 gcloud firestore operations list 命令。此命令会列出正在进行和最近完成的操作。最近几天内完成的操作都会列出:

gcloud firestore operations list

查看操作状态

您可以列出单个长时间运行的操作的详细信息,而不是列出所有长时间运行的操作:

gcloud firestore operations describe operation-name

估计完成时间

操作运行时,查看 state 字段的值可了解操作的总体状态。

用于获取长时间运行的操作的状态的请求也会返回指标 workEstimatedworkCompleted。这些返回的指标包含文档数量。workEstimated 表示操作将处理的预估文档总数。workCompleted 表示目前已处理的文档数。操作完成后,workCompleted 会反映实际处理的文档总数,可能与 workEstimated 的值不同。

workCompleted 除以 workEstimated 可得出粗略的进度估算值。该估计可能不准确,因为它取决于统计信息收集是否存在延迟。

例如,以下是一个索引构建的进度状态:

{
  "operations": [
    {
      "name": "projects/project-id/operations/AyAyMDBiM2U5NTgwZDAtZGIyYi0zYjc0LTIzYWEtZjg1ZGdWFmZWQHEjF0c2Flc3UtcmV4ZWRuaS1uaW1kYRUKSBI",
      "metadata": {
        "@type": "type.googleapis.com/google.firestore.admin.v1.IndexOperationMetadata",
        "common": {
          "operationType": "CREATE_INDEX",
          "startTime": "2020-06-23T16:52:25.697539Z",
          "state": "PROCESSING"
        },
        "progressDocuments": {
          "workCompleted": "219327",
          "workEstimated": "2198182"
        }
       },
    },
    ...

操作完成后,操作说明将包含 "done": true。查看 state 字段的值,了解操作的结果。如果没有在响应中设置 done 字段,则其值为 false。对于进行中的操作,不要依赖 done 值是否存在。

索引构建错误

在管理复合索引和单字段索引例外项时,您可能会遇到索引构建错误。如果 Cloud Firestore 为之编制索引的数据出现问题,索引操作可能会失败。通常这表示您达到了索引限制。例如,操作可能已达到每个文档的索引条目数量上限。

如果索引创建失败,您会在控制台中看到错误消息。确认您没有达到任何索引限制后,请重新尝试您的索引操作。