管理 Cloud Firestore 中的索引

Cloud Firestore 透過要求每個查詢都有索引來確保查詢效能。最基本的查詢所需的索引會自動為您建立。當您使用和測試應用程式時,Cloud Firestore 會產生錯誤訊息,幫助您建立應用程式所需的其他索引。本頁介紹如何管理單一欄位複合索引。

透過錯誤訊息建立缺失索引

如果您嘗試使用未對應到現有索引的範圍子句進行複合查詢,您將收到錯誤。此錯誤訊息包含用於在 Firebase 控制台中建立缺失索引的直接連結。

按照生成的連結訪問 Firebase 控制台,查看自動填充的信息,然後按一下Create

角色和權限

在 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 索引定義參考

使用地形

在資料庫中建立索引

Cloud Firestore 資料庫可以包含單一欄位索引或複合索引。您可以編輯 Terraform 設定檔來為資料庫建立索引。

單一欄位索引

以下範例 Terraform 設定檔在chatrooms集合中的name欄位上建立單一欄位索引:

火庫.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欄位的組合建立複合索引:

火庫.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。

索引建立時間

要建立索引,Cloud 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 索引的資料出現問題,索引作業可能會失敗。最常見的是,這意味著您達到了索引限制。例如,操作可能已達到每個文件的最大索引條目數。

如果索引建立失敗,您會在控制台中看到錯誤訊息。確認未達到任何索引限制後,重新嘗試索引操作。