复合索引配置

Datastore 模式 Firestore 使用索引来处理应用执行的每个查询。 实体发生变化时,这些索引也会随之更新,因此应用执行查询时可快速返回结果。Datastore 模式会自动提供内置索引,但需要预先了解应用要用到哪些复合索引。您可在配置文件中指定应用所需的复合索引。在您测试应用时,Datastore 模拟器可自动生成 Datastore 模式复合索引配置。您可以使用 gcloud 命令行工具,更新供 Datastore 模式生产数据库使用的索引。

系统要求

如需使用 gcloud CLI,您必须已安装 Google Cloud CLI

关于 index.yaml

应用执行的每个 Datastore 模式查询都需要相应的索引。 简单查询(例如对单个属性的查询)的索引是自动创建的。复杂查询的复合索引必须在名为 index.yaml 的配置文件中进行定义。此文件将随应用一起上传,以便在 Datastore 模式数据库中创建复合索引。

如果应用尝试执行的查询需要一个复合索引,但该索引在配置文件中没有对应条目,则 Datastore 模拟器会自动向此文件添加所需条目。可通过修改该文件,手动调整复合索引或创建新的索引。index.yaml 位于 <project-directory>/WEB-INF/ 文件夹中。包含 WEB-INF/appengine-generated/index.yaml 的数据目录默认为 ~/.config/gcloud/emulators/datastore/。如需了解详情,请参阅 Datastore 模拟器项目目录

下面是一个 index.yaml 文件示例:

indexes:

- kind: Task
  ancestor: no
  properties:
  - name: done
  - name: priority
    direction: desc

- kind: Task
  properties:
  - name: collaborators
    direction: asc
  - name: created
    direction: desc

- kind: TaskList
  ancestor: yes
  properties:
  - name: percent_complete
    direction: asc
  - name: type
    direction: asc

index.yaml 的语法采用 YAML 格式。如需详细了解此语法,请参阅 YAML 网站

复合索引定义

index.yaml 包含一个名为 indexes 的列表元素。列表中的每个元素表示一个应用复合索引。

索引元素可包含以下元素:

kind
查询的实体种类。此元素是必需的。
properties

一个要作为复合索引列包含在内的属性列表,按照排序顺序排列:先是等式过滤条件中使用的属性,然后是非等式过滤条件中使用的属性,最后是排序顺序及其方向。

该列表中的每个元素包含以下元素:

name
Datastore 模式下的属性名称。
direction
排序方向:asc 表示升序,desc 表示降序。仅查询的排序顺序中使用的属性需要该元素,且必须与查询使用的方向匹配。默认值为 asc
ancestor

如果查询具有祖先子句,则为 yes。默认值为 no

自动和手动复合索引

当 Datastore 模拟器将生成的复合索引定义添加到 index.yaml 文件中时,会加在下面这一行之后(需要时会插入此行):

# AUTOGENERATED

模拟器将该行以下的所有复合索引定义都视为自动创建的定义,并可能在应用执行查询时更新该行之后的现有定义。

该行以上的所有复合索引定义都被视为手动控制,模拟器不对其进行更新。模拟器仅会更改该行之后的内容,并且仅在完整的 index.yaml 文件未描述应用执行的某个查询时才进行更改。如需控制自动复合索引定义,请将其移到该行上方。

更新复合索引

datastore indexes create 命令会查看本地 Datastore 复合索引配置(index.yaml 文件);如果其中定义的复合索引在 Datastore 模式生产数据库中尚不存在,则您的数据库会相应地创建新复合索引。如需查看有关如何使用 indexes create 的示例,请参阅使用 gcloud CLI 处理开发工作流

如需创建复合索引,数据库必须设置复合索引,然后使用现有数据回填复合索引。复合索引创建时间是设置时间和回填时间的总和:

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

  • 回填时间取决于属于新复合索引的现有数据的数量。属于复合索引的属性值越多,回填复合索引所需的时间就越长。

如果应用执行的查询需要尚未构建完毕的复合索引,查询会引发异常。为避免此情况,在新复合索引构建完毕之前,请务必谨慎部署需要复合索引的应用的新版本。

您可以通过 Google Cloud 控制台中的索引页面查看复合索引的状态。

删除未使用的复合索引

通过复合索引配置更改或移除复合索引时,原始复合索引不会自动从 Datastore 模式数据库中删除。这样,您便能够在构建新复合索引期间让应用的旧版本继续运行,或者在发现新版本存在问题时立即还原到旧版本。

如果您确定不再需要旧复合索引,则可以使用 datastore indexes cleanup 命令将其删除。此命令会删除 index.yaml 本地版本中未提到的 Datastore 模式生产实例的所有复合索引。如需查看有关如何使用 indexes cleanup 的示例,请参阅使用 gcloud CLI 处理开发工作流

命令行参数

如需详细了解用于创建和清除复合索引的命令行参数,请分别参阅 datastore indexes createdatastore indexes cleanup 命令的相关信息。如需详细了解 gcloud CLI 的命令行参数,请参阅 gcloud CLI 参考文档

管理长时间运行的操作

复合索引构建是“长时间运行的操作”,可能需要大量时间才能完成。

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

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

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

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

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

gcloud

gcloud datastore operations list

rest

在使用任何请求数据之前,请先进行以下替换:

  • project-id:您的项目 ID

HTTP 方法和网址:

GET https://datastore.googleapis.com/v1/projects/project-id/operations

如需发送您的请求,请展开以下选项之一:

请参阅下方有关响应的信息。

例如,最近完成的复合索引构建会显示以下信息:

{
  "operations": [
  {
    "name": "projects/project-id/operations/S01vcFVpSmdBQ0lDDCoDIGRiNTdiZDQNmE4YS0yMTVmNWUzZSQadGx1YWZlZAcSMXRzYWVzdS1yZXhlZG5pLW5pbWRhFQpWEg",
    "done": true,
    "metadata": {
      "@type": "type.googleapis.com/google.datastore.admin.v1.IndexOperationMetadata",
      "common": {
        "endTime": "2020-06-23T16:55:29.923562Z",
        "operationType": "CREATE_INDEX",
        "startTime": "2020-06-23T16:55:10Z",
        "state": "SUCCESSFUL"
      },
      "indexId": "CICAJiUpoMK",
      "progressEntities": {
        "workCompleted": "2193027",
        "workEstimated": "2198182"
      }
    },
    "response": {
      "@type": "type.googleapis.com/google.datastore.admin.v1.Index",
      "ancestor": "NONE",
      "indexId": "CICAJiUpoMK",
      "kind": "Task",
      "projectId": "project-id",
           "properties": [
        {
          "direction": "ASCENDING",
          "name": "priority"
        },
        {
          "direction": "ASCENDING",
          "name": "done"
        },
        {
          "direction": "DESCENDING",
          "name": "created"
        }
      ],
      "state": "READY"
    }
  },
  ]
}

描述单个操作

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

gcloud

使用 operations describe 命令显示复合索引构建的状态。

gcloud datastore operations describe operation-name

rest

在使用任何请求数据之前,请先进行以下替换:

  • project-id:您的项目 ID

HTTP 方法和网址:

GET https://datastore.googleapis.com/v1/projects/project-id/operations

如需发送您的请求,请展开以下选项之一:

请参阅下方有关响应的信息。

估计完成时间

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

用于获取长时间运行的操作的状态的请求也会返回指标 workEstimatedworkCompleted。这些返回的指标包含实体数量。workEstimated 基于数据库统计信息估算操作将处理的实体总数。workCompleted 显示到目前为止已处理的实体数。操作完成后,workCompleted 会反映实际处理的实体总数,可能与 workEstimated 的值不同。

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

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

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

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