Cloud Firestore mendukung penggunaan filter rentang dan ketidaksetaraan pada beberapa kolom dalam satu kueri. Anda kini dapat memiliki kondisi rentang dan ketidaksetaraan di beberapa kolom serta menyederhanakan pengembangan aplikasi dengan mendelegasikan implementasi logika pasca-pemfilteran ke Cloud Firestore.
Filter rentang dan ketidaksetaraan di beberapa kolom
Kueri berikut menampilkan semua pengguna yang berusia lebih dari 35 tahun dan tingginya antara 60 hingga 70 tahun menggunakan filter rentang pada usia dan tinggi.
Modular 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);
Android Kotlin+KTX
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 Cloud Firestore.
Di Cloud Firestore, klausa ORDER BY
pada kueri menentukan indeks yang dapat digunakan untuk menyalurkan kueri. Misalnya, kueri ORDER BY a ASC, b ASC
memerlukan indeks gabungan pada kolom a ASC, b ASC
.
Untuk mengoptimalkan performa dan biaya kueri Cloud Firestore, Anda harus mengoptimalkan urutan kolom dalam indeks. Untuk melakukannya, pastikan indeks Anda diurutkan dari kiri ke kanan sehingga kueri disaring ke set data yang mencegah pemindaian entri indeks yang tidak relevan.
Misalkan Anda ingin menelusuri kumpulan karyawan dan menemukan karyawan yang gajinya lebih dari 100.000 dan jumlah tahun pengalamannya lebih besar dari 0. Berdasarkan pemahaman Anda tentang set data, 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.
Mengurutkan kolom indeks berdasarkan kesetaraan yang diikuti oleh rentang yang paling selektif atau kolom ketidaksetaraan
Cloud Firestore menggunakan kolom paling kiri dari indeks gabungan 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 Cloud Firestore. Cloud Firestore menggunakan kolom indeks yang tersisa untuk memenuhi batasan rentang atau ketidaksetaraan lainnya dari kueri. Batasan ini tidak mengurangi jumlah entri indeks yang dipindai Cloud Firestore, tetapi memfilter dokumen yang tidak cocok sehingga jumlah dokumen yang ditampilkan ke klien berkurang.
Untuk mengetahui informasi selengkapnya tentang cara membuat indeks yang efisien, lihat definisi indeks yang sempurna.
Mengurutkan kolom dalam urutan menurun dari selektivitas batasan kueri
Untuk memastikan Cloud Firestore memilih indeks yang optimal untuk kueri Anda, tentukan klausa orderBy()
yang mengurutkan kolom dalam urutan selektivitas batasan kueri secara menurun. Selektivitas yang lebih tinggi cocok dengan subset dokumen yang lebih kecil, sedangkan selektivitas yang lebih rendah cocok dengan subset dokumen yang lebih besar. Pastikan Anda memilih kolom rentang atau ketidaksetaraan dengan selektivitas yang lebih tinggi lebih awal dalam pengurutan indeks daripada kolom dengan selektivitas yang lebih rendah.
Untuk meminimalkan jumlah dokumen yang dipindai dan ditampilkan Cloud Firestore melalui jaringan, Anda harus selalu mengurutkan kolom dalam urutan selektivitas batasan kueri yang menurun. Jika kumpulan hasil tidak dalam urutan yang diperlukan dan kumpulan hasil yang diharapkan berukuran kecil, Anda dapat menerapkan logika sisi klien untuk mengurutkan ulang sesuai dengan ekspektasi pengurutan.
Misalnya, Anda ingin menelusuri kumpulan 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 yang 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 jika pengurutan pada experience
ke kueri akan menghasilkan set dokumen yang sama dan membatalkan pengurutan ulang hasil pada klien, kueri dapat membaca lebih banyak entri indeks yang tidak relevan daripada kueri sebelumnya. Hal ini karena Cloud Firestore selalu lebih memilih indeks yang awalan kolom indeksnya cocok dengan urutan per klausa kueri. Jika experience
ditambahkan ke urutan berdasarkan klausa, Cloud Firestore akan memilih indeks (experience [...], salary [...])
untuk menghitung hasil kueri. Karena tidak ada batasan lain pada experience
, Cloud Firestore akan membaca semua entri indeks dari koleksi employees
sebelum menerapkan filter salary
untuk menemukan kumpulan hasil akhir. Ini berarti entri indeks yang tidak memenuhi filter salary
masih dibaca, sehingga meningkatkan latensi dan biaya kueri.
Harga
Kueri dengan filter rentang dan ketidaksetaraan di beberapa kolom akan ditagih berdasarkan entri dokumen yang dibaca 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. - Cloud Firestore membatasi jumlah kolom rentang atau ketidaksetaraan hingga 10. Hal ini dilakukan untuk mencegah agar kueri tidak menjadi terlalu mahal untuk dijalankan.
Langkah Berikutnya
- Pelajari cara mengoptimalkan kueri.
- Pelajari lebih lanjut cara menjalankan kueri sederhana dan gabungan.
- Memahami cara Cloud Firestore menggunakan indeks.