Ringkasan kueri dengan filter rentang dan ketidaksetaraan di beberapa kolom

Firestore mendukung penggunaan filter rentang dan ketidaksetaraan di beberapa kolom dalam satu kueri. Anda kini dapat memiliki kondisi rentang dan ketidaksetaraan di beberapa kolom dan menyederhanakan pengembangan aplikasi dengan mendelegasikan implementasi logika pasca-pemfilteran ke Firestore.

Filter rentang dan ketidaksetaraan di beberapa kolom

Kueri berikut menampilkan semua pengguna yang usianya lebih dari 35 tahun dan tingginya antara 60 hingga 70 tahun menggunakan filter rentang berdasarkan usia dan tinggi.

Modul web versi 9

  const q = query(
      collection(db, "users"),
      where('age', '>', 35),
      where('height', '>', 60),
      where('height', '<', 70)
    );

Swift

 let query = db.collection("users")
   .whereField("age", isGreaterThan: 35)
   .whereField("height", isGreaterThan: 60)
   .whereField("height", isLessThan: 70)

Objective-C

 FIRQuery *query =
  [[[[self.db collectionWithPath:@"users"]
 queryWhereField:@"age" isGreaterThan:@35]
    queryWhereField:@"height" isGreaterThan:@60]
        queryWhereField:@"height" isLessThan:@70];

Android Java

 Query query = db.collection("users")
  .whereGreaterThan("age", 35)
  .whereGreaterThan("height", 60)
  .whereLessThan("height", 70);

Kotlin+KTX Android

 val query = db.collection("users")
  .whereGreaterThan("age", 35)
  .whereGreaterThan("height", 60)
  .whereLessThan("height", 70)

Java

  db.collection("users")
    .whereGreaterThan("age", 35)
    .whereGreaterThan("height", 60)
    .whereLessThan("height", 70);

Node.js

db.collection("users")
  .where('age', '>', 35),
  .where('height', '>', 60),
  .where('height', '<', 70)

Pertimbangan pengindeksan

Sebelum mulai menjalankan kueri, pastikan Anda telah membaca tentang kueri dan model data Firestore.

Di Firestore, klausa ORDER BY kueri menentukan indeks mana yang dapat digunakan untuk menayangkan kueri. Misalnya, kueri ORDER BY a ASC, b ASC memerlukan indeks komposit pada kolom a ASC, b ASC.

Untuk mengoptimalkan performa dan biaya kueri Firestore, Anda harus mengoptimalkan urutan kolom dalam indeks. Untuk melakukannya, pastikan indeks Anda diurutkan dari kiri ke kanan sehingga kueri akan disaring ke set data yang mencegah pemindaian entri indeks yang tidak relevan.

Misalkan Anda ingin menelusuri kumpulan karyawan dan mencari karyawan yang gajinya lebih dari 100.000 dan yang jumlah tahun pengalamannya lebih besar dari 0. Berdasarkan pemahaman Anda tentang {i>dataset<i}, Anda tahu bahwa batasan gaji lebih selektif daripada batasan pengalaman. Indeks ideal yang akan mengurangi jumlah pemindaian indeks adalah (salary [...], experience [...]). Dengan demikian, kueri yang cepat dan hemat biaya akan mengurutkan salary sebelum experience dan terlihat seperti berikut:

Java

db.collection("employees")
  .whereGreaterThan("salary", 100000)
  .whereGreaterThan("experience", 0)
  .orderBy("salary")
  .orderBy("experience");

Node.js

db.collection("employees")
  .where("salary", ">", 100000)
  .where("experience", ">", 0)
  .orderBy("salary")
  .orderBy("experience");

Python

db.collection("employees")
  .where("salary", ">", 100000)
  .where("experience", ">", 0)
  .order_by("salary")
  .order_by("experience");

Praktik terbaik untuk mengoptimalkan indeks

Saat mengoptimalkan indeks, perhatikan praktik terbaik berikut.

Urutkan kolom indeks berdasarkan kesetaraan diikuti dengan sebagian besar kolom rentang atau ketidaksetaraan selektif

Firestore menggunakan kolom paling kiri pada indeks komposit untuk memenuhi batasan kesetaraan dan batasan rentang atau ketidaksetaraan, jika ada, di kolom pertama kueri orderBy(). Batasan ini dapat mengurangi jumlah entri indeks yang dipindai Firestore. Firestore menggunakan kolom indeks yang tersisa untuk memenuhi batasan rentang atau ketidaksetaraan lainnya dalam kueri. Batasan ini tidak mengurangi jumlah entri indeks yang dipindai Firestore, tetapi memfilter dokumen yang tidak cocok sehingga jumlah dokumen yang ditampilkan ke klien berkurang.

Untuk mengetahui informasi lebih lanjut tentang cara membuat indeks yang efisien, baca definisi indeks sempurna.

Mengurutkan kolom dalam mengurangi urutan selektivitas batasan kueri

Guna memastikan Firestore memilih indeks yang optimal untuk kueri Anda, tentukan klausa orderBy() yang mengurutkan kolom dalam mengurangi urutan selektivitas batasan kueri. Selektif yang lebih tinggi cocok dengan sebagian kecil dokumen, sedangkan selektivitas yang lebih rendah cocok dengan sebagian dokumen yang lebih besar. Pastikan Anda memilih kolom rentang atau ketidaksetaraan dengan selektivitas lebih tinggi lebih awal dalam pengurutan indeks daripada kolom dengan selektivitas lebih rendah.

Untuk meminimalkan jumlah dokumen yang dipindai dan ditampilkan Firestore melalui jaringan, Anda harus selalu mengurutkan kolom dalam urutan menurun selektivitas batasan kueri. Jika kumpulan hasil tidak dalam urutan yang diperlukan dan kumpulan hasil diharapkan berukuran kecil, Anda dapat menerapkan logika sisi klien untuk mengurutkan ulang sesuai ekspektasi pengurutan.

Misalnya, Anda ingin menelusuri koleksi karyawan untuk menemukan karyawan yang gajinya lebih dari 100.000 dan mengurutkan hasilnya berdasarkan tahun pengalaman karyawan tersebut. Jika Anda memperkirakan hanya sejumlah kecil karyawan yang akan memiliki gaji lebih dari 100.000, cara paling efisien untuk menulis kueri adalah sebagai berikut:

Java

db.collection("employees")
  .whereGreaterThan("salary", 100000)
  .orderBy("salary")
  .get()
  .addOnSuccessListener(new OnSuccessListener<QuerySnapshot>() {
        @Override
        public void onSuccess(QuerySnapshot queryDocumentSnapshots) {
          // Order results by `experience`
        }
    });;

Node.js

const querySnapshot = await db.collection('employees')
                              .where("salary", ">", 100000)
                              .orderBy("salary")
                              .get();

// Order results by `experience`

Python

results = db.collection("employees")
            .where("salary", ">", 100000)
            .order_by("salary")
            .stream()

// Order results by `experience`

Meskipun menambahkan pengurutan pada experience ke kueri akan menghasilkan kumpulan dokumen yang sama dan menghilangkan pengurutan ulang hasilnya pada klien, kueri dapat membaca lebih banyak entri indeks yang tidak relevan daripada kueri sebelumnya. Hal ini karena Firestore selalu lebih memilih indeks yang awalan kolom indeksnya cocok dengan urutan demi klausa kueri. Jika experience ditambahkan ke urutan berdasarkan klausa, Firestore akan memilih indeks (experience [...], salary [...]) untuk menghitung hasil kueri. Karena tidak ada batasan lain pada experience, Firestore akan membaca semua entri indeks dari koleksi employees sebelum menerapkan filter salary untuk menemukan kumpulan hasil akhir. Artinya, entri indeks yang tidak memenuhi filter salary akan tetap dibaca, sehingga meningkatkan latensi dan biaya kueri.

Harga

Kueri dengan filter rentang dan ketidaksetaraan di beberapa kolom ditagih berdasarkan pembacaan dokumen dan entri indeks yang dibaca.

Untuk mengetahui informasi selengkapnya, lihat halaman Harga.

Batasan

Selain batasan kueri, perhatikan batasan berikut sebelum menggunakan kueri dengan filter rentang dan ketidaksetaraan di beberapa kolom:

  • Kueri dengan filter rentang atau ketidaksetaraan di kolom dokumen dan hanya batasan kesetaraan pada kunci dokumen (__name__) yang tidak didukung.
  • Firestore membatasi jumlah kolom rentang atau ketidaksetaraan hingga 10. Hal ini untuk mencegah kueri menjadi terlalu mahal untuk dijalankan.

Langkah Berikutnya