管理索引
Firestore 會為每個查詢建立索引,確保查詢效能。系統會自動建立最基本查詢所需的索引。您使用及測試應用程式時,Cloud Firestore 會產生錯誤訊息,協助您建立應用程式需要的其他索引。本頁說明如何管理單一欄位、複合和 [向量][vector] 索引。
透過錯誤訊息建立缺少的索引
如果您嘗試使用範圍子句進行複合查詢,但該子句未對應至現有索引,系統會傳回錯誤。錯誤訊息會提供直接連結,方便您在 Firebase 控制台中建立缺少的索引。
按照產生的連結前往 Firebase 控制台,檢查自動填入的資訊,然後按一下「建立」。
如果需要向量索引,錯誤訊息會包含建立缺少的向量索引的 Google Cloud CLI 指令。執行指令來建立缺少的索引。
角色和權限
如要在 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 主控台中,管理單一欄位索引豁免和複合索引。
建立複合式索引
如要從 GCP 主控台手動建立新的複合式索引,請按照下列步驟操作:
前往 Google Cloud 控制台的「Databases」頁面。
從資料庫清單中選取所需資料庫。
在導覽選單中,按一下「索引」,然後點選「複合」分頁標籤。
按一下「建立索引」。
輸入集合 ID。新增要建立索引的欄位名稱,以及每個欄位的索引模式。按一下「儲存索引」。
新索引會顯示在複合式索引清單中,Firestore 也會開始建立索引。索引建立完成後,索引旁會顯示綠色勾號。
刪除複合式索引
如要刪除複合式索引,請按照下列步驟操作:
前往 Google Cloud 控制台的「Databases」頁面。
從資料庫清單中選取所需資料庫。
在導覽選單中,按一下「索引」,然後點選「複合」分頁標籤。
在複合索引清單中,按一下要刪除的索引的「更多」按鈕
。按一下「刪除」。按一下快訊中的「Delete Index」(刪除索引),確認要刪除這個索引。
新增單一欄位索引豁免設定
單一欄位索引豁免項目可讓您覆寫集合中特定欄位的自動索引設定。您可以透過控制台新增單一欄位豁免:
前往 Google Cloud 控制台的「Databases」頁面。
從資料庫清單中選取所需資料庫。
在導覽選單中,按一下「索引」,然後點選「單一欄位」分頁標籤。
按一下「新增豁免」。
輸入「集合 ID」和「欄位路徑」。
為這個欄位選取新的索引設定。啟用或停用這個欄位的自動更新升序、降序和陣列包含單一欄位索引。
按一下「儲存豁免」。
新增集合層級的豁免
如要定義適用於集合 ID 底下所有欄位的單一欄位索引豁免設定,請按照下列步驟操作:
- 按一下「新增豁免」。
輸入集合群組的「Collection ID」(集合 ID),並將「Field path」(欄位路徑) 設為
*
。選取要套用至集合群組中所有欄位的索引豁免。
按一下「儲存豁免」。
刪除單一欄位索引豁免設定
如要刪除單一欄位索引豁免設定,請執行下列步驟:
前往 Google Cloud 控制台的「Databases」頁面。
從資料庫清單中選取所需資料庫。
在導覽選單中,按一下「索引」,然後點選「單一欄位」分頁標籤。
在單一欄位索引豁免清單中,按一下要刪除豁免的「更多」按鈕
。按一下「刪除」。按一下快訊中的「刪除」,確認要刪除這項豁免。
刪除單一欄位豁免項目後,指定的欄位或子欄位會使用沿用的索引設定。文件欄位會還原為資料庫的自動索引設定。地圖中的子欄位會先繼承上層欄位的豁免設定,再繼承自動索引設定。
使用 Firebase CLI
您也可以使用 Firebase CLI 部署索引。
如要開始使用,請在專案目錄中執行 firebase init firestore
。
設定期間,Firebase CLI 會產生 JSON 檔案,其中包含格式正確的預設索引。編輯檔案以新增更多索引,然後使用 firebase deploy
指令部署檔案。
如要只部署 Firestore 索引和規則,請新增 --only firestore
旗標。
如果您使用 Firebase 控制台編輯索引,請務必同時更新本機索引檔案。請參閱 JSON 索引定義參考資料。
使用 Terraform
在資料庫中建立索引
Firestore 資料庫可以同時包含單一欄位和複合式索引。您可以編輯 Terraform 設定檔,為資料庫建立索引。
單一欄位和複合式索引使用不同的 Terraform 資源類型 (google_firestore_index
和 google_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。
Datastore 模式索引
您也可以使用 Terraform 建立 Datastore 模式索引。
datastore.tf
resource "google_firestore_index" "datastore-mode-index" { project = "project-id" database = "database-id" collection = "chatrooms" fields { field_path = "name" order = "ASCENDING" } fields { field_path = "description" order = "DESCENDING" } query_scope = "COLLECTION_GROUP" api_scope = "DATASTORE_MODE_API" }
從 google_datastore_index 遷移
google_datastore_index
資源已淘汰,將無法在 terraform-provider-google 6.0.0 以上版本中使用。
如果您先前使用 google_datastore_index
資源,可以遷移至 google_firestore_index
。
如要遷移,請按照下列步驟操作:
- 撰寫等效的
google_firestore_index
資源。 - 將現有的 Datastore 模式索引匯入新資源。
- 移除舊
google_datastore_index
資源的參照。 - 從 Terraform 的狀態中移除舊的
google_datastore_index
資源。 - 執行
terraform apply
來套用所有變更。
詳細操作說明如下:
- 根據現有的
google_datastore_index
資源編寫替代google_firestore_index
。請參閱下文瞭解必要變更。 - 判斷索引的 Firestore 資源路徑:
export INDEX_RESOURCE_PATH=$(echo '"projects/${google_datastore_index.datastore-index-resource-name.project}/databases/(default)/collectionGroups/${google_datastore_index.datastore-index-resource-name.kind}/indexes/${google_datastore_index.datastore-index-resource-name.index_id}"' | terraform console | tr -d '"')
將 datastore-index-resource-name 換成現有資源的 Terraform 名稱。
- 將現有的 Datastore 模式索引匯入您在上方建立的
google_firestore_index
資源:terraform import google_firestore_index.firestore-index-resource-name $INDEX_RESOURCE_PATH
將 firestore-index-resource-name 換成現有資源的 Terraform 名稱。
如要進一步瞭解如何匯入 Firestore 索引資源,請參閱 google_firestore_index 參考說明文件。
- 從 Terraform 設定檔中刪除現有的
google_datastore_index
資源。 - 從 Terraform 狀態中移除現有的
google_datastore_index
資源:terraform state rm google_datastore_index.datastore-index-resource-name
如要進一步瞭解如何移除資源,請參閱「移除資源」的 Terraform 頁面。
- 執行
terraform plan
。 驗證輸出內容,確認您並未建立或刪除任何資源。檢查輸出內容,確認匯入作業已順利完成。如果輸出顯示任何欄位變更,請確認這些變更是否為有意進行的操作。如果輸出內容包含類似下列的行:
google_firestore_index.firestore-index-resource-name must be replaced
然後檢查 Terraform 設定檔,看看是否有任何錯誤。
- 確認 Terraform 計畫輸出內容符合需求後,請執行下列指令:
terraform apply
- 將
google_datastore_index
替換為google_firestore_index
。 - 將引數名稱
kind
替換為collection
,但引數值保持不變。 - 將引數名稱
ancestor
替換為query_scope
。將引數值ALL_ANCESTORS
替換為COLLECTION_RECURSIVE
,並將任何其他值替換為COLLECTION_GROUP
。如果沒有ancestor
引數,請新增query_scope
引數,並將值設為COLLECTION_GROUP
。 - 新增引數
api_scope
,並將值設為DATASTORE_MODE_API
。 - 請將每個
properties
例項替換為對應的fields
例項。將每個name
例項替換為field_path
,並將每個direction
例項替換為order
。 設定索引需要幾分鐘的時間。即使是空白資料庫,建立索引也至少需要幾分鐘。
回填時間取決於新索引中現有資料的數量。與索引定義相符的欄位值越多,回填索引所需的時間就越長。
翻譯索引
如要將 google_datastore_index 資源轉換為對應的 google_firestore_index 資源,請複製該資源並進行下列變更:
舉例來說,請參考這個 google_datastore_index
資源:
datastore.tf
resource "google_datastore_index" "legacy" { kind = "foo" properties { name = "property_a" direction = "ASCENDING" } properties { name = "property_b" direction = "ASCENDING" } }
對應的 google_firestore_index
資源會是:
resource "google_firestore_index" "new" { // note: defaults to the provider project project = project // note: defaults to the (default) database database = "(default)" collection = "foo" api_scope = "DATASTORE_MODE_API" // since there was no "ancestor" property set above, use COLLECTION_GROUP here query_scope = "COLLECTION_GROUP" fields { field_path = "property_a" order = "ASCENDING" } fields { field_path = "property_b" order = "ASCENDING" } }
索引建構時間
如要建構索引,Firestore 必須先設定索引,然後使用現有資料回填索引。索引建構時間是設定時間和回填時間的總和:
索引建構作業屬於長時間執行的作業。
啟動索引建構作業後,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
欄位值,以瞭解作業的整體狀態。
用於取得長時間執行作業狀態的要求,也會傳回 workEstimated
和workCompleted
指標。這些指標會針對文件數量傳回。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
值。
建立索引時發生錯誤
管理複合索引和單一欄位索引豁免項目時,可能會遇到索引建構錯誤。如果 Firestore 在建立索引時遇到資料問題,索引作業可能會失敗。最常見的原因是達到索引上限。舉例來說,作業可能已達到每個文件的索引項目數量上限。
如果索引建立失敗,控制台中會顯示錯誤訊息。確認未達到任何索引限制後,請重試索引作業。