توضیحات
تمام ترکیبهای متمایز مقادیر را برای یک سری از عبارات پیدا کنید.
مرحلهی distinct(...) سینتکس مشابهی با select(...) دارد، زیرا یک یا چند عبارت قابل انتخاب را میپذیرد. رشتهها را میتوان زمانی استفاده کرد که عبارت فقط یک ارجاع به فیلد باشد:
مثالها
نود جی اس
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")));
سویفت
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();
پایتون
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() )
جاوا
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();
رفتار
مرحلهی distinct(...) مشابه مرحلهی aggregate(...) بدون گروهها عمل میکند. همچنین به aggregate(...) و select(...) مراجعه کنید.
یافتن مقادیر فیلد متمایز
برای مثال، برای دریافت لیستی از تمام کشورهای موجود در مجموعه cities زیر:
نود جی اس
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"});
کشورهای متمایز را میتوان با استفاده از موارد زیر پیدا کرد:
نود جی اس
const cities = await db.pipeline()
.collection("/cities")
.distinct("country")
.execute();
که نتیجه زیر را تولید میکند:
{ country: "USA" }
{ country: "Canada" }
{ country: "Mexico" }
خروجی متمایز عبارات
همچنین میتوانید ترکیبهای متمایز چندین فیلد یا عبارات پیچیدهتر را پیدا کنید. برای مثال:
نود جی اس
const cities = await db.pipeline()
.collection("/cities")
.distinct(
field("state").toLower().as("normalized_state"),
field("country"))
.execute();
برای دریافت:
{ country: "USA", normalized_state: "ca" }
{ country: "USA", normalized_state: "ny" }
{ country: "Canada", normalized_state: null }
{ country: "Mexico", normalized_state: null }
رفتارهای هم ارزی
رفتار همارزی روی مقادیر متمایز از همان معنای برابریها پیروی میکند.
این بدان معناست که مقادیر معادل، برای مثال مقادیر عددی معادل ریاضی، صرف نظر از انواع اصلی (عدد صحیح ۳۲ بیتی، عدد صحیح ۶۴ بیتی، اعداد ممیز شناور، اعداد اعشاری و غیره)، به عنوان یک مقدار متمایز یکسان در نظر گرفته میشوند.
به عنوان مثال، در یک مجموعه numerics با اسناد مختلف که حاوی مقادیر foo به ترتیب عدد صحیح ۳۲ بیتی 1 ، عدد صحیح ۶۴ بیتی 1L و عدد اعشاری 1.0 هستند، distinct(...) فقط ۱ نتیجه را برمیگرداند.
در چنین مواردی که مقادیر معادل متفاوتی در مجموعه دادهها وجود دارد، مقدار خروجی گروه میتواند هر یک از این مقادیر معادل باشد. در این مثال، این مقدار foo میتواند به صورت 1 ، 1L یا 1.0 برگردانده شود.
حتی اگر قطعی به نظر برسد، نباید سعی کنید برای انتخاب به رفتار یک مقدار خاص تکیه کنید.
میزان استفاده از حافظه
نحوه اجرای مرحله distinct(...) به شاخصهای موجود بستگی دارد. وقتی شاخص مناسبی توسط بهینهساز پرسوجو انتخاب نشده باشد، distinct(...) نیاز به بافر کردن تمام مقادیر متمایز در حافظه دارد.
در صورت وجود تعداد بسیار زیادی مقادیر متمایز، یا مقادیر بسیار بزرگ (مثلاً متمایز بودن روی مقادیر بسیار بزرگ)، این مرحله ممکن است با کمبود حافظه مواجه شود.
در چنین مواردی، باید فیلترهایی را برای محدود کردن مجموعه دادهها به انجام distinct(...) اعمال کنید، یا طبق توصیه، اندیسهایی ایجاد کنید تا از استفاده زیاد از حافظه جلوگیری شود.
ابزار توضیح پرسوجو (Query Explain) اطلاعاتی در مورد طرح اجرای پرسوجوی واقعی و دادههای پروفایلینگ ارائه میدهد تا به اشکالزدایی کمک کند.