aggregate()
का इस्तेमाल करना
फ़ंक्शन, आप निम्न पाइपलाइन चला सकते हैं जो $sum
वांछित परिणाम प्राप्त करने के लिए ऑपरेटर:
const results = await Cart.aggregate([
{ "$addFields": {
"totalPrice": {
"$sum": "$products.subTotal"
}
} },
]);
console.log(JSON.stringify(results, null, 4));
और संबंधित अद्यतन कार्रवाई इस प्रकार है:
db.carts.updateMany(
{ },
[
{ "$set": {
"totalPrice": {
"$sum": "$products.subTotal"
}
} },
]
)
या अगर MongoDB 3.2 और पुराने संस्करणों का उपयोग कर रहे हैं, जहां $sum
केवल $group चरण में उपलब्ध है, आप कर सकते हैं
const pipeline = [
{ "$unwind": "$products" },
{
"$group": {
"_id": "$_id",
"products": { "$push": "$products" },
"userPurchased": { "$first": "$userPurchased" },
"totalPrice": { "$sum": "$products.subTotal" }
}
}
]
Cart.aggregate(pipeline)
.exec(function(err, results){
if (err) throw err;
console.log(JSON.stringify(results, null, 4));
})
उपरोक्त पाइपलाइन में, पहला कदम है $unwind
ऑपरेटर
{ "$unwind": "$products" }
जो डेटा को एक ऐरे के रूप में स्टोर करने पर काफी काम आता है। जब खोलना ऑपरेटर को सूची डेटा फ़ील्ड पर लागू किया जाता है, तो यह सूची डेटा फ़ील्ड के प्रत्येक तत्व के लिए एक नया रिकॉर्ड उत्पन्न करेगा, जिस पर खोलना लागू किया गया है। यह मूल रूप से डेटा को समतल करता है।
यह अगले पाइपलाइन चरण के लिए एक आवश्यक ऑपरेशन है, $group
चरण जहाँ आप फ़्लैट किए गए दस्तावेज़ों को _id
. द्वारा समूहित करते हैं फ़ील्ड, इस प्रकार गैर-सामान्यीकृत दस्तावेज़ों को उनके मूल स्कीमा में प्रभावी ढंग से पुनर्समूहित करता है।
$group
पाइपलाइन ऑपरेटर SQL के GROUP BY
. के समान है खंड। SQL में, आप GROUP BY
का उपयोग नहीं कर सकते हैं जब तक आप किसी भी एकत्रीकरण फ़ंक्शन का उपयोग नहीं करते हैं। उसी तरह, आपको MongoDB (जिसे संचायक कहा जाता है) में भी एकत्रीकरण फ़ंक्शन का उपयोग करना होगा। आप संचयकों के बारे में यहां
अधिक पढ़ सकते हैं। ।
इसमें $group
कोड>
ऑपरेशन, totalPrice
की गणना करने का तर्क और मूल फ़ील्ड लौटाना accumulators . आपको totalPrice
मिलता है प्रत्येक व्यक्ति को संक्षेप में subTotal
$sum
. के साथ प्रति समूह मान के रूप में:
"totalPrice": { "$sum": "$products.subTotal }
दूसरी अभिव्यक्ति
"userPurchased": { "$first": "$userPurchased" },
एक userPurchased
लौटाएगा $first
. का उपयोग करके प्रत्येक समूह के लिए पहले दस्तावेज़ से मूल्य . इस प्रकार से पहले मूल दस्तावेज़ स्कीमा को प्रभावी ढंग से फिर से बनाना $unwind
यहां एक बात ध्यान देने योग्य है कि एक पाइपलाइन को क्रियान्वित करते समय, MongoDB पाइप ऑपरेटरों को एक दूसरे में जोड़ता है। "पाइप" यहाँ लिनक्स अर्थ लेता है:एक ऑपरेटर का आउटपुट निम्नलिखित ऑपरेटर का इनपुट बन जाता है। प्रत्येक ऑपरेटर का परिणाम दस्तावेजों का एक नया संग्रह है। तो मोंगो उपरोक्त पाइपलाइन को निम्नानुसार निष्पादित करता है:
collection | $unwind | $group => result
एक साइड नोट के रूप में, पाइपलाइन को समझने में मदद करने के लिए या इसे डिबग करने के लिए आपको अप्रत्याशित परिणाम मिलने चाहिए, केवल पहले पाइपलाइन ऑपरेटर के साथ एकत्रीकरण चलाएं। उदाहरण के लिए, मोंगो शेल में एग्रीगेशन को इस प्रकार चलाएँ:
db.cart.aggregate([
{ "$unwind": "$products" }
])
यह देखने के लिए परिणाम देखें कि क्या products
सरणी ठीक से deconstructed है। यदि वह अपेक्षित परिणाम देता है, तो अगला जोड़ें:
db.cart.aggregate([
{ "$unwind": "$products" },
{
"$group": {
"_id": "$_id",
"products": { "$push": "$products" },
"userPurchased": { "$first": "$userPurchased" },
"totalPrice": { "$sum": "$products.subTotal" }
}
}
])
अंतिम पाइपलाइन चरण तक पहुंचने तक चरणों को दोहराएं।
यदि आप फ़ील्ड को अपडेट करना चाहते हैं तो आप $out
अंतिम चरण के रूप में पाइपलाइन चरण। यह एकत्रीकरण पाइपलाइन के परिणामी दस्तावेजों को उसी संग्रह में लिखेगा, इस प्रकार तकनीकी रूप से संग्रह को अद्यतन करेगा।
var pipeline = [
{ "$unwind": "$products" },
{
"$group": {
"_id": "$_id",
"products": { "$push": "$products" },
"userPurchased": { "$first": "$userPurchased" },
"totalPrice": { "$sum": "$products.subTotal" }
}
},
{ "$out": "cart" } // write the results to the same underlying mongo collection
]
अपडेट करें
अपडेट और क्वेरी दोनों करने के लिए, आप तब find()
. जारी कर सकते हैं अपडेटेड जोंस यानी
Cart.aggregate(pipeline)
.exec(function(err, results){
if (err) throw err;
Cart.find().exec(function(err, docs){
if (err) return handleError(err);
console.log(JSON.stringify(docs, null, 4));
})
})
वादों का उपयोग करके, आप वैकल्पिक रूप से ऐसा कर सकते हैं
Cart.aggregate(pipeline).exec().then(function(res)
return Cart.find().exec();
).then(function(docs){
console.log(JSON.stringify(docs, null, 4));
});