توضیحات
مرحله ورودی subcollection(...) انجام عملیات پیوند والد-فرزند را با استفاده از فیلد داخلی __name__ آسان میکند.
مراحل اضافی را میتوان به مرحله subcollection(...) زنجیر کرد تا فیلتر یا تجمیع روی اسناد تودرتو انجام شود. توجه داشته باشید که هرگونه ارجاع به فیلد مورد استفاده در مراحل بعدی، به اسناد مجموعه تودرتو اشاره دارد، نه به سند والد. برای ارجاع به فیلدها در حوزه والد، ابتدا از مرحله let(...) برای تعریف متغیرها استفاده کنید، سپس به آن متغیرها در حوزه محلی ارجاع دهید.
مثالها
نود جی اس
db.pipeline()
.collection("/restaurants")
.add_fields(subcollection("reviews")
.aggregate(average("rating").as("avg_rating"))
.toScalarExpression()
.as("avg_rating"))
رفتار
مرحلهی subcollection(...) باید در چارچوب یک subquery استفاده شود. این مرحله از __name__ (مرجع سند) سند فعلی در محدودهی والد برای تعیین اینکه کدام زیرمجموعه باید واکشی شود، استفاده میکند. برای مثال، اگر سند والد /restaurants/pizza-place باشد، آنگاه subcollection("reviews") تمام اسناد موجود در مجموعهی /restaurants/pizza-place/reviews را برمیگرداند.
اگر مرجع سند تغییر نام داده شده است، یا تعریف فیلد با __name__ امکانپذیر نیست، میتوانید به صورت دستی پیوند را مانند زیر بنویسید:
نود جی اس
db.pipeline()
.collection("/restaurants")
.let(field("__name__").as("restaurant_name"))
.add_fields(db.pipeline()
.collectionGroup("reviews")
.where(field("__name__").parent().equals(variable("restaurant_name")))
.aggregate(average("rating").as("avg_rating"))
.toScalarExpression()
.as("avg_rating"))
هنوز هم امکانپذیر است، زیرا اساساً این مرحله فقط یک تغییر نحوی روی این قالب اتصال پیچیدهتر است.
برای مدارک زیر:
نود جی اس
const restaurant1 = db.collection("restaurants").document("pizza-place");
const restaurant2 = db.collection("restaurants").document("urban-bite");
const restaurant3 = db.collection("restaurants").document("nacho-house");
await restaurant1.create({ name: "Pizza Place" });
await restaurant2.create({ name: "Urban Bite" });
await restaurant3.create({ name: "Nacho House" });
await restaurant1.collection("reviews").doc("1").create({ rating: 5 });
await restaurant1.collection("reviews").doc("1").create({ rating: 2 });
await restaurant2.collection("reviews").doc("1").create({ rating: 3 });
await restaurant2.collection("reviews").doc("1").create({ rating: 4 });
await restaurant2.collection("reviews").doc("1").create({ rating: 5 });
کوئری زیر هر رستوران را بازیابی کرده و خلاصه نظرات آن را در یک فیلد جدید review_summary ارائه میدهد:
نود جی اس
const results = await db.pipeline()
.collectionGroup("restaurants")
.add_fields(subcollection("reviews")
.aggregate(
countAll().as("review_count"),
average("rating").as("avg_rating"))
.asScalarExpression()
.as("review_summary"))
.execute();
و نتایج زیر را تولید میکند:
{ name: "Pizza Place", review_summary: { review_count: 2, avg_rating: 3.5 } },
{ name: "Urban Bite", review_summary: { review_count: 3, avg_rating: 4.0 } },
{ name: "Nacho House", review_summary: { review_count: 0, avg_rating: null } },