Mengelola indeks

Firestore memastikan performa kueri dengan mewajibkan indeks untuk setiap kueri. Indeks yang diperlukan untuk kueri paling dasar dibuat otomatis untuk Anda. Saat Anda menggunakan dan menguji aplikasi, Cloud Firestore membuat pesan error yang membantu Anda membuat indeks tambahan yang dibutuhkan aplikasi. Halaman ini menjelaskan cara mengelola indeks kolom tunggal, komposit, dan [vector][vector].

Membuat indeks yang hilang melalui pesan error

Jika Anda mencoba kueri gabungan dengan klausa rentang yang tidak memetakan ke indeks yang ada, Anda akan menerima error. Pesan error menyertakan link langsung untuk membuat indeks yang tidak ada di Firebase console.

Ikuti link yang dihasilkan untuk membuka Firebase console, tinjau info yang terisi secara otomatis, lalu klik Buat.

Jika indeks vektor diperlukan, pesan error akan menyertakan perintah Google Cloud CLI untuk membuat indeks vektor yang tidak ada. Jalankan perintah untuk membuat indeks yang tidak ada.

Peran dan izin

Sebelum dapat membuat indeks di Firestore, pastikan Anda ditunjuk untuk salah satu peran berikut:

  • roles/datastore.owner
  • roles/datastore.indexAdmin
  • roles/editor
  • roles/owner

Jika Anda telah menentukan peran khusus, tetapkan semua izin berikut untuk membuat indeks:

  • datastore.indexes.create
  • datastore.indexes.delete
  • datastore.indexes.get
  • datastore.indexes.list
  • datastore.indexes.update

Menggunakan Konsol Google Cloud Platform

Dari Google Cloud Platform Console, Anda dapat mengelola pengecualian pengindeksan kolom tunggal dan indeks komposit.

Buat indeks gabungan

Untuk membuat indeks komposit baru secara manual dari konsol GCP:

  1. Di konsol Google Cloud, buka halaman Databases.

    Buka Databases

  2. Pilih database yang diperlukan dari daftar database.

  3. Di menu navigasi, klik Indexes, lalu klik tab Composite.

  4. Klik Buat Indeks.

  5. Masukkan ID Koleksi. Tambahkan nama kolom yang ingin Anda indeksasikan dan mode indeks untuk setiap kolom. Klik Simpan Indeks.

Indeks baru Anda akan muncul dalam daftar indeks komposit dan Firestore akan mulai membuat indeks Anda. Setelah indeks selesai dibuat, Anda akan melihat tanda centang hijau di samping indeks.

Menghapus indeks komposit

Untuk menghapus indeks komposit:

  1. Di konsol Google Cloud, buka halaman Databases.

    Buka Databases

  2. Pilih database yang diperlukan dari daftar database.

  3. Di menu navigasi, klik Indexes, lalu klik tab Composite.

  4. Dalam daftar indeks komposit, klik tombol Lainnya untuk indeks yang ingin dihapus. Klik Delete.

  5. Konfirmasi bahwa Anda ingin menghapus indeks ini dengan mengklik Hapus Indeks dari pemberitahuan.

Menambahkan pengecualian indeks kolom tunggal

Dengan pengecualian indeks kolom tunggal, Anda dapat mengganti setelan indeks otomatis untuk kolom tertentu dalam koleksi. Anda dapat menambahkan pengecualian kolom tunggal dari konsol:

  1. Di konsol Google Cloud, buka halaman Databases.

    Buka Databases

  2. Pilih database yang diperlukan dari daftar database.

  3. Di menu navigasi, klik Indexes, lalu klik tab Single Field.

  4. Klik Tambahkan Pengecualian.

  5. Masukkan ID Koleksi dan Jalur kolom.

  6. Pilih setelan pengindeksan baru untuk kolom ini. Aktifkan atau nonaktifkan indeks kolom tunggal menaik, menurun, dan array-contains yang diperbarui secara otomatis untuk kolom ini.

  7. Klik Simpan Pengecualian.

Menambahkan pengecualian tingkat koleksi

Untuk menentukan pengecualian indeks kolom tunggal yang berlaku untuk semua kolom dalam ID koleksi:

  1. Klik Tambahkan Pengecualian.
  2. Masukkan ID Koleksi untuk grup koleksi dan tetapkan Jalur kolom sebagai *.

    Pilih kolom yang akan dikecualikan

  3. Pilih pengecualian pengindeksan yang ingin Anda terapkan untuk semua kolom dalam grup koleksi.

  4. Klik Simpan Pengecualian.

Menghapus pengecualian indeks kolom tunggal

Untuk menghapus pengecualian indeks satu kolom, lakukan langkah berikut:

  1. Di konsol Google Cloud, buka halaman Databases.

    Buka Databases

  2. Pilih database yang diperlukan dari daftar database.

  3. Di menu navigasi, klik Indexes, lalu klik tab Single Field.

  4. Dalam daftar pengecualian indeks kolom tunggal, klik tombol Lainnya untuk pengecualian yang ingin dihapus. Klik Delete.

  5. Konfirmasi bahwa Anda ingin menghapus pengecualian ini dengan mengklik Hapus dari pemberitahuan.

Saat Anda menghapus pengecualian kolom tunggal, kolom atau subkolom yang ditentukan akan menggunakan setelan pengindeksan yang diwariskan. Kolom dokumen akan dikembalikan ke setelan indeks otomatis database Anda. Subkolom dalam peta mewarisi pengecualian apa pun pada kolom induk sebelum mewarisi setelan indeks otomatis.

Menggunakan Firebase CLI

Anda juga dapat men-deploy indeks dengan Firebase CLI. Untuk memulai, jalankan firebase init firestore di direktori project Anda. Selama penyiapan, Firebase CLI menghasilkan file JSON dengan indeks default dalam format yang tepat. Edit file untuk menambahkan lebih banyak indeks dan men-deploynya dengan perintah firebase deploy.

Untuk hanya men-deploy indeks dan aturan Firestore, tambahkan flag --only firestore.

Jika mengedit indeks menggunakan Firebase console, pastikan Anda juga memperbarui file indeks lokal. Lihat referensi definisi indeks JSON.

Menggunakan Terraform

Membuat indeks dalam database

Database Firestore dapat menyertakan indeks kolom tunggal dan komposit. Anda dapat mengedit file konfigurasi Terraform agar dapat membuat indeks untuk database Anda. Indeks kolom tunggal dan komposit menggunakan jenis resource Terraform yang berbeda (google_firestore_index dan google_firestore_field).

Indeks Mode Native Firestore dan Mode Datastore didukung.

Indeks kolom tunggal

Contoh file konfigurasi Terraform berikut membuat indeks kolom tunggal di kolom name dalam koleksi chatrooms:

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 {}
}
  • Ganti project-id dengan project ID Anda. Project ID harus unik.
  • Ganti database-id dengan ID database Anda.

Indeks komposit

Contoh file konfigurasi Terraform berikut membuat indeks komposit untuk kombinasi kolom name dan kolom description dalam koleksi chatrooms:

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"
  }

}
  • Ganti project-id dengan project ID Anda. Project ID harus unik.
  • Ganti database-id dengan ID database Anda.

Indeks vektor

Contoh file konfigurasi Terraform berikut membuat indeks vektor di kolom embedding dalam koleksi chatrooms:

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 {}
    }
  }
}
  • Ganti project-id dengan project ID Anda. Project ID harus unik.
  • Ganti database-id dengan ID database Anda.

Indeks mode Datastore

Anda juga dapat membuat indeks Mode Datastore menggunakan Terraform.

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"
}
Bermigrasi dari google_datastore_index

Resource google_datastore_index tidak digunakan lagi dan tidak akan tersedia di terraform-provider-google versi 6.0.0 dan yang lebih baru.

Jika sebelumnya menggunakan resource google_datastore_index, Anda dapat bermigrasi ke google_firestore_index. Anda dapat melakukan migrasi dengan melakukan hal berikut:

  1. Tulis resource google_firestore_index yang setara.
  2. Impor indeks mode Datastore yang ada ke resource baru.
  3. Hapus referensi ke resource google_datastore_index lama.
  4. Hapus resource google_datastore_index lama dari status Terraform.
  5. Menjalankan terraform apply untuk menerapkan perubahan.

Berikut petunjuk yang lebih mendetail:

  1. Tulis google_firestore_index pengganti berdasarkan resource google_datastore_index yang ada. Lihat di bawah untuk mengetahui perubahan yang diperlukan.
  2. Tentukan jalur resource Firestore indeks Anda:

    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 '"')
    

    Ganti datastore-index-resource-name dengan nama Terraform dari resource yang ada.

  3. Impor indeks mode Datastore yang ada ke resource google_firestore_index yang Anda buat di atas:

    terraform import google_firestore_index.firestore-index-resource-name $INDEX_RESOURCE_PATH
    

    Ganti firestore-index-resource-name dengan nama Terraform dari resource yang ada.

    Untuk informasi selengkapnya tentang cara mengimpor resource indeks Firestore, lihat dokumentasi referensi google_firestore_index.

  4. Hapus resource google_datastore_index yang ada dari file konfigurasi Terraform Anda.
  5. Hapus resource google_datastore_index yang ada dari status Terraform:

    terraform state rm google_datastore_index.datastore-index-resource-name
    

    Untuk informasi selengkapnya tentang cara menghapus resource, lihat halaman Terraform tentang Menghapus Resource.

  6. Jalankan terraform plan. Verifikasi output untuk mengonfirmasi bahwa Anda tidak membuat atau menghancurkan resource apa pun.

    Periksa output untuk memastikan impor berhasil diselesaikan. Jika output menunjukkan perubahan pada kolom, pastikan perubahan ini memang diinginkan. Jika output menyertakan baris yang mirip dengan:

    google_firestore_index.firestore-index-resource-name must be replaced
    

    lalu periksa file konfigurasi Terraform Anda untuk melihat apakah ada kesalahan.

  7. Setelah Anda puas dengan output rencana Terraform, jalankan:

    terraform apply
    

  8. Menerjemahkan indeks

    Untuk menerjemahkan resource google_datastore_index ke resource google_firestore_index yang setara, salin dan buat perubahan berikut:

    • Ganti google_datastore_index dengan google_firestore_index.
    • Ganti nama argumen kind dengan collection, tetapi biarkan nilai argumen tetap sama.
    • Ganti nama argumen ancestor dengan query_scope. Ganti nilai argumen ALL_ANCESTORS dengan COLLECTION_RECURSIVE dan nilai lainnya dengan COLLECTION_GROUP. Jika tidak ada argumen ancestor, tambahkan argumen query_scope dengan nilai COLLECTION_GROUP.
    • Tambahkan argumen api_scope dengan nilai DATASTORE_MODE_API.
    • Untuk setiap instance properties, ganti dengan instance fields yang sesuai. Ganti setiap instance name dengan field_path dan setiap instance direction dengan order.

    Misalnya, pertimbangkan resource google_datastore_index ini:

    datastore.tf

    resource "google_datastore_index" "legacy" {
      kind = "foo"
    
      properties {
        name = "property_a"
        direction = "ASCENDING"
      }
    
      properties {
        name = "property_b"
        direction = "ASCENDING"
      }
    }
    

    Resource google_firestore_index yang setara adalah:

    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"
      }
    }
    

    Waktu build indeks

    Untuk mem-build indeks, Firestore harus menyiapkan indeks, lalu mengisi ulang indeks dengan data yang ada. Waktu build indeks adalah jumlah waktu penyiapan dan waktu pengisian ulang:

    • Menyiapkan indeks memerlukan waktu beberapa menit. Waktu build minimum untuk indeks adalah beberapa menit, meskipun untuk database yang kosong.

    • Waktu pengisian ulang bergantung pada jumlah data yang ada dalam indeks baru. Semakin banyak nilai kolom yang cocok dengan definisi indeks, semakin lama waktu yang diperlukan untuk mengisi ulang indeks.

    Build indeks merupakan operasi yang berjalan lama.

    Setelah Anda memulai build indeks, Firestore akan menetapkan nama unik untuk operasi tersebut. Nama operasi diawali dengan projects/[PROJECT_ID]/databases/(default)/operations/, misalnya:

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

    Namun, Anda dapat tidak menyertakan awalan saat menentukan nama operasi untuk perintah describe.

    Mencantumkan semua operasi yang berjalan lama

    Untuk mencantumkan operasi yang berjalan lama, gunakan perintah gcloud firestore operations list. Perintah ini mencantumkan operasi yang sedang berlangsung dan yang baru saja selesai. Operasi tercantum selama beberapa hari setelah selesai:

    gcloud firestore operations list
    

    Memeriksa status operasi

    Alih-alih mencantumkan semua operasi yang berjalan lama, Anda dapat mencantumkan detail satu operasi:

    gcloud firestore operations describe operation-name

    Memperkirakan waktu penyelesaian

    Saat operasi berjalan, lihat nilai kolom state untuk mengetahui status operasi secara keseluruhan.

    Permintaan untuk status operasi yang berjalan lama juga menampilkan metrik workEstimated dan workCompleted. Metrik ini ditampilkan untuk sejumlah dokumen. workEstimated menunjukkan perkiraan jumlah total dokumen yang akan diproses dalam operasi. workCompleted menunjukkan jumlah dokumen yang diproses sejauh ini. Setelah operasi selesai, workCompleted mencerminkan jumlah total dokumen yang sebenarnya diproses yang mungkin berbeda dari nilai workEstimated.

    Bagilah workCompleted dengan workEstimated untuk mengetahui perkiraan kasar dari progresnya. Perkiraan ini mungkin tidak akurat karena tergantung pada pengumpulan statistik yang tertunda.

    Misalnya, berikut adalah status progres dari suatu build indeks:

    {
      "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"
            }
           },
        },
        ...
    

    Saat operasi selesai, deskripsi operasi akan berisi "done": true. Lihat nilai kolom state untuk menemukan hasil operasi. Jika kolom done tidak ditetapkan dalam respons, maka nilainya adalah false. Jangan bergantung pada keberadaan nilai done untuk operasi yang sedang berlangsung.

    Error dalam mem-build indeks

    Anda mungkin mengalami error dalam mem-build indeks saat mengelola indeks gabungan dan pengecualian indeks satu kolom. Operasi pengindeksan dapat gagal jika Firestore menemukan masalah dengan data yang diindeks. Biasanya, ini berarti Anda mencapai batas indeks. Misalnya, operasi mungkin telah mencapai jumlah entri indeks maksimum per dokumen.

    Jika pembuatan indeks gagal, Anda melihat pesan error di konsol. Setelah memverifikasi bahwa Anda tidak mencapai batas indeks, coba lagi operasi indeks.