复合索引配置

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 create 和 datastore 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 字段的值可了解操作的总体状态。

用于获取长时间运行的操作的状态的请求也会返回指标 workEstimated 和 workCompleted。这些返回的指标包含实体数量。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 值的存在。