2013-04-10 8 views
7

निम्नलिखित पर विचार करें के पहले दस्तावेज़ का क्षेत्र अपने दस्तावेज़ संग्रह में संग्रहीत है UsersMongoDB एकत्रीकरण ढांचा - लायें नेस्टेड सरणी

{ 
    _id : "User1", 
    joined : ISODate("2011-03-02"), 
    likes : { 
      sublikes: [ 
         {WebsiteID:'001': WebsiteName: 'ABCD'}, 
         {WebsiteID:'002': WebsiteName: '2BC2'}, 
         {WebsiteID:'003': WebsiteName: '3BC3'}, 
         //........... 
         //........... 
         {WebsiteID:'999999': WebsiteName: 'SOME_NAME'} 
        ] 
      } 
} 

अब MongoDB एकत्रीकरण ढांचे का उपयोग कर रहा लाने की जरूरत है कि

collection.aggregate([ 
         { $project: { 
          _id: 1, 
          "UserID": "$_id", 
          "WebsiteName": "$likes.sublikes[0]['WebsiteName']" 
         } 
         }, 
         { $match: { _id: 'User1'} } 
         ], function (err, doc) { 
///Not able to get the WebsiteName: 'ABCD' 
}); 

हैं मैं $unwind का उपयोग करता हूं, दस्तावेज़ थोक हो जाता है (विशेष रूप से उपर्युक्त मामले में), इसलिए मैं इसे किसी सरणी में केवल पहले आइटम (अन्य लोगों के बावजूद) प्राप्त करने के लिए अनदेखा नहीं करना चाहता हूं

क्या कोई मुझे इस बात का संकेत दे सकता है कि उस तक पहुंच कैसे है और उस क्षेत्र का नाम बदलें?


अद्यतन 1: यहां तक ​​कि मैंने "WebsiteName": "$likes.sublikes.0.WebsiteName" के साथ प्रोजेक्ट करने की कोशिश की। :-(

अद्यतन काम नहीं किया 2:। - ओपन मुद्दा https://jira.mongodb.org/browse/SERVER-4589

अब $at काम नहीं करता है के रूप में एक त्रुटि फेंकता:

{ [MongoError: exception: invalid operator '$at'] 
    name: 'MongoError', 
    errmsg: 'exception: invalid operator \'$at\'', 
    code: 15999, 
    ok: 0 } 

तो $unwind

का उपयोग कर जब तक
// Array Remove - By John Resig (MIT Licensed) 
Array.prototype.remove = function(from, to) { 
    var rest = this.slice((to || from) + 1 || this.length); 
    this.length = from < 0 ? this.length + from : from; 
    return this.push.apply(this, rest); 
}; 
+0

क्या आप इसके बजाय $ स्लाइस (http://docs.mongodb.org/manual/reference/projection/slice/) ऑपरेटर के साथ सामान्य क्वेरीिंग का उपयोग नहीं करेंगे: 'db.col.find ({_ id: ' उपयोगकर्ता 1 '}, {' likes.sublikes ': {$ टुकड़ा: 1}}) '? – Sammaye

+1

जिरा में खुला मुद्दा जिसे आपने संदर्भित किया है (SERVER-4589) एक सुविधा अनुरोध है, इसलिए '$ at' ऑपरेटर अभी तक मौजूद नहीं है। प्रगति को ट्रैक करने के लिए आप जिरा में फीचर को वोट/देख सकते हैं। – Stennie

+1

एफवाईआई, यदि आप एक इंडेक्स का लाभ उठाना चाहते हैं तो आपको एकत्रीकरण पाइपलाइन की शुरुआत में अपना '$ मैच' भी होना चाहिए। मोंगोडीबी दस्तावेज में [ऑप्टिमाइज़िंग प्रदर्शन] (http://docs.mongodb.org/manual/core/aggregation/#optimizing-performance) विवरण देखें। – Stennie

उत्तर

10

अपना परिणाम प्राप्त करने का सबसे आसान तरीका एक सामान्य खोज क्वेरी और $slice ऑपरेटर का उपयोग किया जाता है:

db.collection.find({_id: "User1"}, {"likes.sublikes": {$slice: 1}}) 

(MongoDB 2.4.1 में के रूप में) एकत्रीकरण ढांचे $slice या सरणी अनुक्रमित (: SERVER-6074 और SERVER-4589 वोट/घड़ी सुविधा अनुरोधों) का समर्थन नहीं करता।

आप एकत्रीकरण ढांचे $unwind, $group का उपयोग करने और $first ऑपरेटर, जैसे आप ऐसा कर सकते:

db.collection.aggregate([ 
    { $match: { 
     _id : "User1" 
    }}, 
    { $unwind: "$likes.sublikes" }, 
    { $group: { 
     _id: "$_id", 
     like: { $first: "$likes.sublikes" } 
    }}, 
    { $project: { 
     _id: 0, 
     "UserID": "$_id", 
     "WebsiteName": "$like.WebsiteName" 
    }} 
]) 

सामान्य $slice सबसे शक्तिशाली विकल्प होना चाहिए।

+1

बहुत अच्छा .. यह काम करता है ... –

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