管理 Cloud Firestore 中的索引

Cloud Firestore 會要求每個查詢都必須有索引,以確保查詢效能。系統會自動建立最基本查詢所需的索引。您使用及測試應用程式時,Cloud Firestore 會產生錯誤訊息,協助您建立應用程式需要的其他索引。本頁面說明如何管理單一欄位複合式向量索引。

透過錯誤訊息建立缺少的索引

如果您嘗試使用範圍子句進行複合查詢,但該範圍子句未對應至現有索引,系統會傳回錯誤。錯誤訊息中包含直接連結,可在 Firebase 控制台中建立缺少的索引。

點選產生的連結前往 Firebase 控制台,查看系統自動填入的資訊,然後按一下「建立」

如果需要向量索引,錯誤訊息會包含 Google Cloud CLI 指令,用於建立缺少的向量索引。執行指令來建立缺少的索引。

角色和權限

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 資源類型 (google_firestore_indexgoogle_firestore_field)。

單一欄位索引

以下範例 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。

向量索引

以下範例 Terraform 設定檔會在 chatrooms 集合中,針對 embedding 欄位建立向量索引:

firestore.tf

resource "google_firestore_index" "vector-index" {
  project = "project-id"
  database = "database-id"
  collection = "chatrooms"

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

  fields {
    field_path = "embedding"
    vector_config {
      dimension = 128
      flat {}
    }
  }
}
  • 請將 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 在索引資料時遇到問題,索引作業就可能會失敗。這通常表示您已達到索引上限。例如,作業可能已達到每個文件的索引項目數量上限。

如果索引建立作業失敗,控制台中會顯示錯誤訊息。確認未達到任何索引限制後,請重試索引作業。