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