ब्यौरा
aggregate(...) स्टेज में, पिछले स्टेज से मिले दस्तावेज़ों से एग्रीगेट किए गए नतीजे (जैसे कि गिनती, योग) मिलते हैं.
अगर ग्रुपिंग एक्सप्रेशन दिया जाता है, तो यह दस्तावेज़ों को दिए गए एक्सप्रेशन के आधार पर ग्रुप करता है. इसके बाद, हर ग्रुप पर एक्यूमलेटर फ़ंक्शन लागू करता है.
उदाहरण
ग्रुप-बाय के बिना एग्रीगेशन के लिए, aggregate(...) स्टेज में एक या उससे ज़्यादा एलियास वाले एग्रीगेटर एक्सप्रेशन होते हैं:
Node.js
const cities = await db.pipeline()
.collection("/cities")
.aggregate(
countAll().as("total"),
average("population").as("avg_population")
)
.execute();
ग्रुपिंग के साथ एग्रीगेशन के लिए, एग्रीगेटर के अलावा अन्य ग्रुप की ज़रूरत होती है:
Node.js
const result = await db.pipeline()
.collectionGroup('citites')
.aggregate({
accumulators: [
countAll().as('cities'),
field('population').sum().as('total_popoluation')
],
groups: [field('location.state').as('state')]
})
.execute();
व्यवहार
ग्रुपिंग के बिना एग्रीगेशन
इन दस्तावेज़ों का cities कलेक्शन बनाओ:
Node.js
await db.collection('cities').doc('SF').set({name: 'San Francisco', state: 'CA', country: 'USA', population: 870000});
await db.collection('cities').doc('LA').set({name: 'Los Angeles', state: 'CA', country: 'USA', population: 3970000});
await db.collection('cities').doc('NY').set({name: 'New York', state: 'NY', country: 'USA', population: 8530000});
await db.collection('cities').doc('TOR').set({name: 'Toronto', state: null, country: 'Canada', population: 2930000});
await db.collection('cities').doc('MEX').set({name: 'Mexico City', state: null, country: 'Mexico', population: 9200000});
शहरों की कुल संख्या और उनकी औसत जनसंख्या का पता लगाने के लिए:
Node.js
const cities = await db.pipeline()
.collection("/cities")
.aggregate(
countAll().as("total"),
average("population").as("avg_population")
)
.execute();
जिससे यह मिलता है:
{avg_population: 5100000, total: 5}
ग्रुप पर एग्रीगेशन करना
groups आर्ग्युमेंट देकर, हर अलग ग्रुप पर एग्रीगेशन किया जा सकता है.
उदाहरण के लिए, हर देश और हर राज्य में सबसे ज़्यादा जनसंख्या वाले शहर का पता लगाने के लिए:
Node.js
const cities = await db.pipeline()
.collection("/cities")
.aggregate({
accumulators: [
countAll().as("number_of_cities"),
maximum("population").as("max_population")
],
groups: ["country", "state"]
})
.execute();
जिससे ये जानकारी मिलती है:
{country: "USA", state: "CA", max_population: 3970000, number_of_cities: 2},
{country: "USA", state: "NY", max_population: 8530000, number_of_cities: 1},
{country: "Canada", state: null, max_population: 2930000, number_of_cities: 1},
{country: "Mexico", state: null, max_population: 9200000, number_of_cities: 1}
ग्रुप बनाने के लिए जटिल एक्सप्रेशन
aggregate(...) स्टेज में, सिर्फ़ फ़ील्ड वैल्यू के हिसाब से ग्रुप बनाने के अलावा, जटिल एक्सप्रेशन के नतीजों के हिसाब से भी ग्रुप बनाए जा सकते हैं. select(...) स्टेज में मान्य होने वाले किसी भी एक्सप्रेशन को ग्रुपिंग कुंजी के तौर पर इस्तेमाल किया जा सकता है.
इससे कैलकुलेट की गई वैल्यू या शर्तों के आधार पर, अपनी ज़रूरत के हिसाब से ग्रुपिंग की जा सकती है.
उदाहरण के लिए, अगर आपको यह जानना है कि राज्य फ़ील्ड में कोई वैल्यू है या नहीं, तो इसके हिसाब से ग्रुप बनाएं. साथ ही, हर ग्रुप में कुल जनसंख्या का पता लगाएं:
Node.js
const cities = await db.pipeline()
.collection("/cities")
.aggregate({
accumulators: [
sum("population").as("total_population")
],
groups: [equal(field("state"), null).as("state_is_null")]
})
.execute();
यह वैल्यू दिखेगी:
{state_is_null: true, total_population: 12130000}
{state_is_null: false, total_population: 13370000}
एग्रीगेटर के व्यवहार
हर फ़ंक्शन (जैसे, count, sum, avg) के एग्रीगेशन के तरीके के बारे में जानने के लिए, एग्रीगेट फ़ंक्शन वाले पेज पर जाएं.
ग्रुप की के काम करने के तरीके
दस्तावेज़ों को ग्रुप करते समय, Firestore यह तय करने के लिए समानता के सिमैंटिक का इस्तेमाल करता है कि वैल्यू एक ही ग्रुप से जुड़ी हैं या नहीं.
इसका मतलब है कि एक जैसी वैल्यू, जैसे कि गणित के हिसाब से एक जैसी संख्या वाली वैल्यू, भले ही उनका ओरिजनल टाइप कुछ भी हो (32-बिट पूर्णांक, 64-बिट पूर्णांक, फ़्लोटिंग पॉइंट नंबर, decimal128 वगैरह), उन सभी को एक साथ ग्रुप किया जाता है.
उदाहरण के लिए, अगर किसी कलेक्शन numerics में अलग-अलग दस्तावेज़ों में 32-बिट पूर्णांक 1, 64-बिट पूर्णांक 1L, और फ़्लोटिंग-पॉइंट नंबर 1.0 की वैल्यू मौजूद हैं, तो उन सभी को एक ही ग्रुप में इकट्ठा किया जाएगा.foo foo के हिसाब से ग्रुप करके गिनती करने पर, यह नतीजा मिलेगा:
{foo: 1.0, count: 3}
डेटासेट में एक जैसी अलग-अलग वैल्यू मौजूद होने पर, ग्रुप की आउटपुट वैल्यू इनमें से कोई भी वैल्यू हो सकती है.
इस उदाहरण में, foo, 1, 1L या 1.0 हो सकता है.
भले ही, यह तय किया जा सकता हो कि कौनसी वैल्यू चुनी जाएगी, लेकिन आपको नहीं मानना चाहिए कि हमेशा एक ही वैल्यू चुनी जाएगी.
मेमोरी का उपयोग
एग्रीगेशन कैसे किया जाएगा, यह उपलब्ध इंडेक्स पर निर्भर करता है. जब क्वेरी ऑप्टिमाइज़र कोई सही इंडेक्स नहीं चुनता है, तो एग्रीगेट को मेमोरी में सभी ग्रुप को बफ़र करना होता है.
अगर ग्रुप की संख्या बहुत ज़्यादा है या हर ग्रुप बहुत बड़ा है (जैसे, बड़ी वैल्यू के हिसाब से ग्रुप बनाना), तो इस स्टेज में आउट ऑफ़ मेमोरी हो सकती है.
ऐसे मामलों में, आपको फ़िल्टर लागू करने चाहिए, ताकि डेटासेट को एग्रीगेट किया जा सके. इसके अलावा, छोटे/कम फ़ील्ड पर ग्रुपिंग की जा सकती है या ज़्यादा मेमोरी इस्तेमाल से बचने के लिए, सुझाए गए इंडेक्स बनाए जा सकते हैं. क्वेरी के बारे में जानकारी देने वाली सुविधा, क्वेरी के एक्ज़ीक्यूशन प्लान और प्रोफ़ाइलिंग डेटा के बारे में जानकारी देगी. इससे डीबग करने में मदद मिलेगी.