Berbeda (Tahap Transformasi)
Deskripsi
Temukan semua kombinasi nilai yang berbeda untuk serangkaian ekspresi.
Tahap distinct(...) memiliki sintaksis yang mirip dengan select(...) karena mengambil satu atau
beberapa ekspresi yang dapat dipilih. String dapat digunakan saat ekspresinya hanya berupa
referensi kolom:
Contoh
Node.js
let cities = await db.pipeline() .collection("cities") .distinct("country") .execute(); cities = await db.pipeline() .collection("cities") .distinct( field("state").toLower().as("normalizedState"), field("country")) .execute();
Web
let cities = await execute(db.pipeline() .collection("cities") .distinct("country")); cities = await execute(db.pipeline() .collection("cities") .distinct( field("state").toLower().as("normalizedState"), field("country")));
Swift
let results = try await db.pipeline() .collection("books") .distinct([ Field("author").toUpper().as("author"), Field("genre") ]) .execute()
Kotlin
Android
var cities = db.pipeline() .collection("cities") .distinct("country") .execute() cities = db.pipeline() .collection("cities") .distinct( field("state").toLower().alias("normalizedState"), field("country") ) .execute()
Java
Android
Task<Pipeline.Snapshot> cities; cities = db.pipeline() .collection("cities") .distinct("country") .execute(); cities = db.pipeline() .collection("cities") .distinct( field("state").toLower().alias("normalizedState"), field("country")) .execute();
Python
from google.cloud.firestore_v1.pipeline_expressions import Field cities = client.pipeline().collection("cities").distinct("country").execute() cities = ( client.pipeline() .collection("cities") .distinct(Field.of("state").to_lower().as_("normalizedState"), "country") .execute() )
Java
Pipeline.Snapshot cities1 = firestore.pipeline().collection("cities").distinct("country").execute().get(); Pipeline.Snapshot cities2 = firestore .pipeline() .collection("cities") .distinct(toLower(field("state")).as("normalizedState"), field("country")) .execute() .get();
Perilaku
Tahap distinct(...) berfungsi mirip dengan tahap
aggregate(...) tanpa grup. Lihat juga
aggregate(...) dan
select(...).
Menemukan Nilai Kolom Unik
Misalnya, untuk mendapatkan daftar setiap negara dalam koleksi cities
berikut:
Node.js
await db.collection("cities").doc("SF").set({name: "San Francisco", state: "CA", country: "USA"});
await db.collection("cities").doc("LA").set({name: "Los Angeles", state: "CA", country: "USA"});
await db.collection("cities").doc("NY").set({name: "New York", state: "NY", country: "USA"});
await db.collection("cities").doc("TOR").set({name: "Toronto", state: null, country: "Canada"});
await db.collection("cities").doc("MEX").set({name: "Mexico City", state: null, country: "Mexico"});
Negara yang berbeda dapat ditemukan menggunakan:
Node.js
const cities = await db.pipeline()
.collection("/cities")
.distinct("country")
.execute();
yang hasilnya adalah sebagai berikut:
{ country: "USA" }
{ country: "Canada" }
{ country: "Mexico" }
Output Ekspresi Unik
Anda juga dapat menemukan kombinasi unik dari beberapa kolom, atau ekspresi yang lebih rumit. Contoh:
Node.js
const cities = await db.pipeline()
.collection("/cities")
.distinct(
field("state").toLower().as("normalized_state"),
field("country"))
.execute();
untuk mendapatkan:
{ country: "USA", normalized_state: "ca" }
{ country: "USA", normalized_state: "ny" }
{ country: "Canada", normalized_state: null }
{ country: "Mexico", normalized_state: null }
Perilaku Setara
Perilaku setara pada nilai unik menggunakan semantik yang sama dengan kesetaraan.
Artinya, nilai yang setara, misalnya nilai numerik yang secara matematis setara, terlepas dari jenis aslinya (bilangan bulat 32-bit, bilangan bulat 64-bit, bilangan floating point, bilangan desimal, dll.), akan dianggap sebagai nilai unik yang sama.
Sebagai contoh, dalam koleksi numerics dengan berbagai dokumen yang masing-masing berisi nilai foo
bilangan bulat 32-bit 1, bilangan bulat 64-bit 1L, dan floating point 1.0,
distinct(...) hanya akan menampilkan 1 hasil.
Jika ada nilai setara yang berbeda dalam set data,
nilai output kelompok dapat berupa salah satu dari nilai setara tersebut.
Dalam contoh ini, nilai foo dapat ditampilkan sebagai 1, 1L, atau 1.0.
Meskipun tampak deterministik, Anda tidak boleh mencoba mengandalkan perilaku satu nilai spesifik yang dipilih.
Pemakaian Memori
Cara tahap distinct(...) dieksekusi bergantung pada indeks yang tersedia. Jika
tidak ada indeks yang sesuai yang dipilih oleh pengoptimal kueri, distinct(...)
harus melakukan buffering untuk semua nilai unik dalam memori.
Jika ada nilai unik dalam jumlah besar, atau nilai yang sangat besar (misalnya, unik dalam nilai yang sangat besar), tahap ini bisa saja kehabisan memori.
Dalam kasus seperti ini, sebaiknya terapkan filter untuk membatasi set data tempat Anda akan
menjalankan tahap distinct(...), atau buat indeks sesuai rekomendasi untuk menghindari penggunaan memori yang besar.
Query Explain akan memberikan informasi tentang rencana eksekusi kueri yang sebenarnya dan data profiling untuk membantu proses debug.