2015-02-27 8 views
6

के साथ एक दस्तावेज़ में एक औसत अद्यतन कर रहा है मैं निम्नलिखित MongoDB दस्तावेज़ है:MongoDB: 2 नेस्टेड सरणियों

{ 
    _id: ObjectId(), 
    company_name: "Name", 
    registered: 2/21/2015 2:00, 
    trucks: [ 
     { 
      truck_id: "TEB7622", 
      weight: 88.33, 
      capacity: 273.333, 
      length: 378.333, 
      width: 377.383, 
      average_grade: 2.5, 
      grades: [ 
       { 
        grade_number: 4, 
        timestamp: 2/21/2015 2:00 
       } 
      ] 
     }, 
     { 
      truck_id: "TEB5572", 
      weight: 854.33, 
      capacity: 2735.333, 
      length: 378.333, 
      width: 37.383, 
      average_grade: 3.8, 
      grades: [ 
       { 
        grade_number: 4, 
        timestamp: 2/21/2015 2:00 
       } 
      ] 
     } 
    ] 

} 

मैं प्रत्येक ट्रक average_grade सभी grade_numbers जोड़कर अद्यतन करना चाहते। मेरी समस्या यह है कि grade_numbers मैं एक सरणी के भीतर एक सरणी में जोड़ने की कोशिश कर रहा हूं। मैंने ट्रक और ग्रेड सरणी दोनों को खोलने के लिए $unwind का उपयोग करने का प्रयास किया है।

db.col.aggregate([ 
    {$unwind: "$trucks"}, 
    {$unwind: "$trucks.grades"}, 
    { $project: { 
     "_id": "$trucks.truck_id", 
     "trucks.average_grade": { $avg: { $sum: "trucks.grades.grade_number"} } 
     } 
    }]) 

मैं अपने क्वेरी के लिए अधिक कुछ जोड़ने के लिए है है:

यह है क्वेरी मैं का उपयोग कर की कोशिश की? मैं trucks.average_grades के सभी अपडेट करना चाहता हूं, क्योंकि दस्तावेज़ में उनमें से बहुत से मैं अपडेट करने का प्रयास कर रहा हूं।

+0

आप दस्तावेज़ – styvane

+0

@ माइकल 9 अपडेट करने के लिए एकत्रीकरण का उपयोग नहीं कर सकते हैं तो मुझे दो प्रश्नों को सही तरीके से चलाने की आवश्यकता है? औसत प्राप्त करने के लिए औसत और एक प्राप्त करने के लिए एक? क्या मुझे औसत को "चर" पर स्टोर करना है? – suecarmol

+0

डबल नेस्टेड सरणी एक अच्छा विचार नहीं है यदि आपको उनके अंदर डेटा पूछने की आवश्यकता है। वे ठीक हैं अगर डेटा सिर्फ प्रदर्शन के लिए है। शायद आपको डेटा मॉडल पर पुनर्विचार करना चाहिए? हो सकता है कि प्रत्येक ट्रक 'company_id' फ़ील्ड के साथ अपना स्वयं का दस्तावेज़ होना चाहिए? या प्रत्येक ग्रेड का अपना दस्तावेज़? आप एक सामान्य क्वेरी के लिए डबल अनइंड एकत्रीकरण पाइपलाइन पर भरोसा नहीं करना चाहते हैं, इसलिए जब तक क्वेरी असामान्य नहीं है, तब तक मैं नीचे दिए गए समाधान की अनुशंसा नहीं करता। – wdberkeley

उत्तर

6

आप दस्तावेज़ को अपडेट करने के लिए aggregation का उपयोग नहीं कर सकते हैं, लेकिन आप निश्चित रूप से उस डेटा को प्राप्त करने के लिए इसका उपयोग कर सकते हैं, जिसे आप अपडेट के लिए उपयोग करना चाहते हैं। सबसे पहले, मैंने देखा कि grades सरणी के अंदर grade ऑब्जेक्ट के आसपास कुछ {} गुम हैं। आप दोबारा जांचना चाहेंगे कि आपकी दस्तावेज़ संरचना पोस्ट की गई है। दूसरा, आपकी समेकन क्वेरी के साथ कुछ समस्याएं हैं।

  1. $avg ऑपरेटर एक $group खंड, नहीं एक $project अंदर काम करता है।
  2. जब आप $avg का उपयोग करते हैं, तो आपको $sum का उपयोग करने की आवश्यकता नहीं है।
  3. आप trucks.grades.grade.grade_number औसत करना चाहते हैं, जो वास्तव में ग्रेड के सांख्यिक मूल्य को धारण करता है। यही है, आप grades और grade_number के बीच grade गुम हैं।

आप उन मुद्दों को हल करने हैं, तो आप एक प्रश्न निम्न के समान मिलती है:

db.col.aggregate([ 
    { "$unwind": "$trucks" }, 
    { "$unwind": "$trucks.grades" }, 
    { "$group": 
     { 
      "_id": "$trucks.truck_id", 
      "average_grade": { "$avg": "$trucks.grades.grade_number" } 
     } 
    } 
]); 

अपने नमूना दस्तावेज़ के लिए, कि रिटर्न:

{ "_id" : "TEB5572", "average_grade" : 4 } 
{ "_id" : "TEB7622", "average_grade" : 4 } 

अब आप इस जानकारी का उपयोग कर सकते हैं average_grade फ़ील्ड अपडेट करें। यदि आप MongoDB संस्करण 2.6 या उच्चतर का उपयोग कर रहे हैं, तो aggregate विधि कर्सर वापस कर देगी। आप उस कर्सर के माध्यम से पुन: प्रयास कर सकते हैं और तदनुसार दस्तावेज़ अपडेट कर सकते हैं।

इस उदाहरण में, मैं दस्तावेजों है कि एक विशेष truck_id उनके trucks सरणी के अंदर है और एकत्रीकरण क्वेरी की गणना एक साथ average_grade अद्यतन करने के लिए आगे बढ़ना के लिए खोज। आप अपनी आवश्यकताओं के अनुरूप इसे संशोधित कर सकते हैं। समेकन क्वेरी के साथ, कोड इस तरह दिखता है।

// Get average grade for each truck and assign results to cursor. 
var cur = db.col.aggregate([ 
    { "$unwind": "$trucks" }, 
    { "$unwind": "$trucks.grades" }, 
    { "$group": 
     { 
      "_id": "$trucks.truck_id", 
      "average_grade": { "$avg": "$trucks.grades.grade_number" } 
     } 
    } 
]); 

// Iterate through results and update average grade for each truck. 
while (cur.hasNext()) { 
    var doc = cur.next(); 
    db.col.update({ "trucks.truck_id": doc._id }, 
        { "$set": { "trucks.$.average_grade": doc.average_grade }}, 
        { "multi": true}); 
} 
+0

हां, वह था। बहुत बहुत धन्यवाद। – suecarmol

+0

खुशी हुई यह मदद की! –

संबंधित मुद्दे