الوصف
تسهّل مرحلة الإدخال subcollection(...) إجراء عمليات ربط بين مستندات رئيسية وفرعية
باستخدام الحقل __name__ المضمّن.
يمكن ربط مراحل إضافية بالمرحلة subcollection(...) لتنفيذ فلترة أو تجميع للمستندات المتداخلة. يُرجى العِلم أنّ أي مراجع للحقول مستخدَمة في المراحل اللاحقة تشير إلى المستندات من المجموعة المتداخلة، وليس إلى المستند الرئيسي. للإشارة إلى الحقول في النطاق الرئيسي،
استخدِم أولاً مرحلة let(...) لتحديد المتغيّرات، ثم
أشِر إلى هذه المتغيّرات في النطاق المحلي.
أمثلة
Node.js
db.pipeline()
.collection("/restaurants")
.add_fields(subcollection("reviews")
.aggregate(average("rating").as("avg_rating"))
.toScalarExpression()
.as("avg_rating"))
السلوك
يجب استخدام المرحلة subcollection(...) في سياق استعلام فرعي. يستخدم هذا الحقل __name__ (مرجع المستند) للمستند الحالي في النطاق الرئيسي لتحديد المجموعة الفرعية التي سيتم جلبها. على سبيل المثال، إذا كان المستند الرئيسي هو /restaurants/pizza-place، سيعرض subcollection("reviews") جميع المستندات من المجموعة /restaurants/pizza-place/reviews.
إذا تمت إعادة تسمية مرجع المستند، أو إذا تعذّر تحديد حقل باستخدام __name__، يمكنك كتابة عملية الربط يدويًا على النحو التالي:
Node.js
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"))
لا يزال ذلك ممكنًا لأنّ هذه المرحلة هي في الأساس مجرد تبسيط لغوي لهذا التنسيق الأكثر تعقيدًا.
بالنسبة إلى المستندات التالية:
Node.js
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 جديد:
Node.js
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 } },