インデックスの管理

Firestore では、すべてのクエリにインデックスを使用することで、クエリのパフォーマンスを維持しています。最も基本的なクエリに必要なインデックスは、自動的に作成されます。Cloud Firestore を使用すると、アプリを使用してテストする際に、アプリで必要な追加のインデックスを簡単に作成できます。このページでは、単一フィールド インデックス複合インデックスの管理方法について説明します。

不足しているインデックスをエラー メッセージから作成する

一方、既存のインデックスに対応しない range 句で複合クエリを実行すると、エラーが発生します。このエラー メッセージに含まれている Firebase コンソールのリンクを使用すると、不足しているインデックスを作成できます。

Firebase コンソールへのリンクをクリックして、自動的に入力された情報を確認し、[作成] をクリックします。

ロールと権限

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

Google Cloud Platform Console を使用する

Google Cloud Platform Console から、単一フィールドのインデックス除外と複合インデックスを管理できます。

複合インデックスを作成する

GCP Console から新しい複合インデックスを手動で作成するには:

  1. Google Cloud コンソールで [Database] ページに移動します。

    [データベース] に移動

  2. データベースのリストから、必要なデータベースを選択します。

  3. ナビゲーション メニューで、[インデックス] をクリックし、[複合] タブをクリックします。

  4. [インデックスを作成] をクリックします。

  5. コレクション ID を入力します。インデックスを作成するフィールドの名前と各フィールドのインデックス モードを追加します。[インデックスの保存] をクリックします。

複合インデックスのリストに新しいインデックスが表示され、Firestore がインデックスの作成を開始します。インデックスの作成が完了すると、インデックスの横に緑色のチェックマークが表示されます。

複合インデックスを削除する

複合インデックスを削除するには:

  1. Google Cloud コンソールで [Database] ページに移動します。

    [データベース] に移動

  2. データベースのリストから、必要なデータベースを選択します。

  3. ナビゲーション メニューで、[インデックス] をクリックし、[複合] タブをクリックします。

  4. 複合インデックスのリストで、削除するインデックスのその他ボタン をクリックします。[削除] をクリックします。

  5. アラートから [インデックスの削除] をクリックして、このインデックスを削除することの確認を行います。

単一フィールドのインデックス除外を追加する

単一フィールドのインデックス除外では、コレクションの特定のフィールドの自動インデックス設定をオーバーライドできます。コンソールから、単一フィールド除外を追加できます。

  1. Google Cloud コンソールで [データベース] ページに移動します。

    [データベース] に移動

  2. データベースのリストから、必要なデータベースを選択します。

  3. ナビゲーション メニューで [インデックス] をクリックし、[単一フィールド] タブをクリックします。

  4. [除外を追加] をクリックします。

  5. コレクション IDフィールドパスを入力します。

  6. このフィールドの新しいインデックス設定を選択します。このフィールドに対して自動的に更新される昇順、降順、配列を含む単一フィールド インデックスを有効または無効にします。

  7. [除外を保存] をクリックします。

コレクション レベルの除外を追加する

コレクション ID の下にあるすべてのフィールドに適用される単一フィールド インデックス除外を定義するには:

  1. [除外を追加] をクリックします。
  2. コレクション グループの [コレクション ID] を入力し、[フィールドパス] を * に設定します。

    除外するフィールドを選択

  3. コレクション グループ内のすべてのフィールドに適用するインデックス除外を選択します。

  4. [除外を保存] をクリックします。

単一フィールド インデックス除外を削除する

単一フィールド インデックス除外を削除するには、次のようにします。

  1. Google Cloud コンソールで [Database] ページに移動します。

    [データベース] に移動

  2. データベースのリストから、必要なデータベースを選択します。

  3. ナビゲーション メニューで [インデックス] をクリックし、[単一フィールド] タブをクリックします。

  4. 単一フィールド インデックス除外リストで、削除する [さらに表示] ボタン をクリックします。[削除] をクリックします。

  5. アラートから [削除] をクリックして、この除外を削除することの確認を行います。

単一フィールド除外を削除すると、指定されたフィールドまたはサブフィールドは継承されたインデックス設定を使用します。ドキュメント フィールドは、データベースの自動インデックス設定に戻ります。マップ内のサブフィールドは、親フィールドの除外を継承してから、自動インデックス設定を継承します。

Firebase CLI を使用する

Firebase CLI を使用してインデックスをデプロイすることもできます。まず、プロジェクト ディレクトリで firebase init firestore を実行します。設定中に、デフォルトのインデックスが正しい形式で含まれている JSON ファイルが Firebase CLI により生成されます。ファイルを編集してインデックスを追加し、firebase deploy コマンドを使用してデプロイします。

Firestore のインデックスとルールのみをデプロイするには、--only firestore フラグを追加します。

Firebase コンソールでインデックスを編集する場合は、必ずローカル インデックス ファイルも更新してください。JSON インデックス定義リファレンスをご覧ください。

Terraform を使用

データベースのインデックスを作成する

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 によりインデックスがセットアップされ、既存データにインデックスがバックフィルされる必要があります。インデックスの構築時間は、セットアップ時間とバックフィル時間の合計です。

  • インデックスの設定には数分かかります。インデックスの最小構築時間は、空のデータベースであっても数分です。

  • バックフィル時間は、新しいインデックスに既存のデータがどの程度存在するかによって異なります。インデックス定義に一致するフィールド値が多いほど、インデックスのバックフィルにかかる時間が長くなります。

インデックスの構築は長時間実行オペレーションになります。

インデックスの構築を開始すると、Firestore によりオペレーションに一意の名前が割り当てられます。次のように、オペレーション名の先頭には projects/[PROJECT_ID]/databases/(default)/operations/ という文字列が付きます。

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

ただし、describe コマンドのオペレーション名を指定するときは、接頭辞を省略できます。

すべての長時間実行オペレーションの一覧表示

長時間実行オペレーションを一覧表示するには、gcloud firestore operations list コマンドを使用します。このコマンドは、実行中のオペレーションと最近完了したオペレーションを一覧表示します。オペレーションは、完了後数日間一覧表示されます。

gcloud firestore operations list

オペレーションのステータスを確認する

すべての長時間実行オペレーションを一覧表示する代わりに、1 つのオペレーションの詳細を一覧表示できます。

gcloud firestore operations describe operation-name

完了時間の見積もり

オペレーションを実行すると、state フィールドの値で、オペレーション全体のステータスが確認できます。

長時間実行オペレーションのステータスをリクエストすると、workEstimatedworkCompleted の指標も合わせて返されます。これらの指標はドキュメント数で返されます。workEstimated には、オペレーションで処理される推定の合計ドキュメント数が表示されます。workCompleted には、これまでに処理されたドキュメント数が表示されます。オペレーションが完了すると、workCompleted には実際に処理されたドキュメントの合計数が反映されます。これは workEstimated の値とは異なる場合があります。

進行した割合を大まかに得るには、workCompletedworkEstimated で割ります。この割合は、最新の統計情報コレクションとの間に遅延があるために正確ではない可能性があります。

例として、インデックス構築の進行状況を次に示します。

{
  "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 の値の有無は参考になりません。

インデックス構築エラー

複合インデックスと単一フィールド インデックスの除外を管理するときに、インデックス構築エラーが発生することがあります。Firestore がインデックスを作成しているデータで問題を検出すると、インデックス作成オペレーションに失敗する可能性があります。多くの場合、インデックスの上限に達すると、この問題が発生します。たとえば、オペレーションでドキュメントあたりの最大インデックス エントリ数に達した可能性があります。

インデックスの作成に失敗すると、コンソールにエラー メッセージが表示されます。インデックスの上限に達していないことを確認した後、インデックス オペレーションを再試行します。