त्रुटि इसलिए है क्योंकि यह अब आपके $unwind के बाद एक सरणी नहीं है
और इसलिए अब $size
।
ऐसा लगता है कि आप कुछ मौजूदा उत्तरों को "मर्ज" करने का प्रयास कर रहे हैं, यह समझे बिना कि वे क्या कर रहे हैं। आप वास्तव में यहां क्या चाहते हैं $filter
और $size
db.collection.aggregate([
{ "$project": {
"total": {
"$size": {
"$filter": {
"input": "$Array",
"cond": { "$eq": [ "$$this.field1", "a" ] }
}
}
}
}}
])
या $reduce
का इस्तेमाल करके "पहिया को फिर से शुरू करें"
:
db.collection.aggregate([
{ "$project": {
"total": {
"$reduce": {
"input": "$Array",
"initialValue": 0,
"in": {
"$sum": [
"$$value",
{ "$cond": [{ "$eq": [ "$$this.field1", "a" ] }, 1, 0] }
}
}
}
}}
])
या आप $unwindके साथ क्या करने का प्रयास कर रहे थे? कोड>
, आप वास्तव में $group
फिर से "गिनने" के लिए कि कितने मैच थे:
db.collection.aggregate([
{ "$unwind": "$Array" },
{ "$match": { "Array.field1": "a" } },
{ "$group": {
"_id": "$_id",
"total": { "$sum": 1 }
}}
])
आधुनिक MongoDB वातावरण के लिए पहले दो रूप "इष्टतम" हैं। अंतिम फ़ॉर्म $unwind
के साथ
और $group
एक "विरासत" निर्माण है जो वास्तव में MongoDB 2.6 के बाद से इस प्रकार के संचालन के लिए आवश्यक नहीं है, हालांकि कुछ अलग ऑपरेटरों के साथ।
उन पहले दो में हम मूल रूप से field1
. की तुलना कर रहे हैं प्रत्येक सरणी तत्व का मान, जबकि यह अभी भी एक सरणी है। दोनों $filter
और $reduce
आधुनिक ऑपरेटरों को मौजूदा सरणी के साथ काम करने के लिए डिज़ाइन किया गया है। एग्रीगेशन $eq का इस्तेमाल करके हर एक पर समान तुलना की जाती है
ऑपरेटर जो दिए गए तर्क "बराबर" हैं या नहीं, इस पर आधारित एक बूलियन मान देता है। इस मामले में प्रत्येक सरणी सदस्य पर "a"
. के अपेक्षित मान पर ।
$filter
के मामले में
, सरणी वास्तव में बरकरार रहती है सिवाय किसी भी तत्व के जो "cond"
में आपूर्ति की गई शर्त को पूरा नहीं करता है सरणी से हटा दिए जाते हैं। चूंकि हमारे पास अभी भी आउटपुट के रूप में एक "सरणी" है, इसलिए हम <का उपयोग कर सकते हैं। कोड>$आकार
ऑपरेटर उस फ़िल्टर स्थिति के संसाधित होने के बाद शेष सरणी तत्वों की संख्या को मापने के लिए।
$reduce
दूसरी ओर सरणी तत्वों के माध्यम से काम करता है और प्रत्येक तत्व और एक संग्रहीत "संचयक" मान पर एक अभिव्यक्ति प्रदान करता है, जिसे हमने "initialValue"
के साथ प्रारंभ किया था . इस मामले में वही $eq
परीक्षण $cond
में लागू किया जाता है
ऑपरेटर। यह एक "टर्नरी" या if/then/else
. है सशर्त ऑपरेटर जो एक परीक्षण अभिव्यक्ति की अनुमति देता है जो एक बूलियन मान देता है फिर
मान जब सत्य
या अन्य
मान जब गलत
।
उस अभिव्यक्ति में हम 1
. लौटाते हैं या 0
क्रमशः और उस लौटाए गए मूल्य और वर्तमान "संचयक" को जोड़ने के समग्र परिणाम की आपूर्ति करें "$$value"
$sum
के साथ
इन्हें एक साथ जोड़ने के लिए ऑपरेटर।
अंतिम रूप इस्तेमाल किया गया $unwind
सरणी पर। यह वास्तव में जो करता है वह सरणी सदस्यों को मूल दस्तावेज़ में प्रत्येक सरणी सदस्य और उसके संबंधित मूल फ़ील्ड के लिए "नया दस्तावेज़" बनाने के लिए deconstructs करता है। यह प्रत्येक सरणी सदस्य के लिए मुख्य दस्तावेज़ को प्रभावी रूप से "कॉपी" करता है।
एक बार जब आप $unwind
दस्तावेजों की संरचना को "चापलूसी" रूप में बदल दिया गया है। यही कारण है कि आप बाद में $matchकर सकते हैं कोड>
बेमेल दस्तावेज़ों को निकालने के लिए पाइपलाइन चरण।
यह हमें $group
पर लाता है
जो एक सामान्य कुंजी से संबंधित सभी सूचनाओं को "एक साथ वापस लाने" के लिए लागू होता है। इस मामले में यह _id
है मूल दस्तावेज़ का क्षेत्र, जिसे निश्चित रूप से $अनविंड करें
. जैसे ही हम एक ही दस्तावेज़ के रूप में इस "सामान्य कुंजी" पर वापस जाते हैं, हम $sum
संचायक।
यदि हम शेष "सरणी" वापस चाहते हैं, तो आप कर सकते हैं $पुश
और केवल शेष सदस्यों के साथ सरणी का पुनर्निर्माण करें:
{ "$group": {
"_id": "$_id",
"Array": { "$push": "$Array" },
"total": { "$sum": 1 }
}}
लेकिन निश्चित रूप से $size
का उपयोग करने के बजाय
एक अन्य पाइपलाइन चरण में, हम अभी भी "गिनती" कर सकते हैं जैसे हमने पहले ही $sum