ब्यौरा
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 } },