Deskripsi
Mencari tahu nilai unik kolom atau ekspresi dari tahap sebelumnya.
Sintaksis
Tahap distinct memiliki sintaksis yang mirip dengan select. Diperlukan satu atau beberapa ekspresi yang dapat dipilih
untuk memilih dan menemukan nilai unik. String dapat digunakan saat
ekspresinya hanya berupa referensi kolom:
Node.js
const cities = await db.pipeline()
.collection('/cities')
.distinct("country")
.execute();
const cities = await db.pipeline()
.collection('/cities')
.distinct(
field("state").toLower().as("normalized_state"),
field("country"))
.execute();
Contoh klien
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
var cities = db.pipeline() .collection("cities") .distinct("country") .execute() cities = db.pipeline() .collection("cities") .distinct( field("state").toLower().alias("normalizedState"), field("country") ) .execute()
Java
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
Dari segi perilaku proyeksi, distinct mirip seperti select dengan penghapusan duplikat, sehingga ekspresi yang dapat dipilih yang tersedia untuk select
juga dapat digunakan untuk distinct.
Tahap distinct berfungsi mirip dengan tahap aggregate tanpa grup.
Lihat juga Tahap Aggregate dan Tahap 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, 1L bilangan bulat 64-bit, dan 1.0 floating point,
distinct hanya akan menampilkan 1 hasil.
Jika ada nilai setara yang berbeda dalam set data,
nilai output grup 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.