2014-05-05 8 views
11

में यूनियन प्रदर्शन करें मैं सोच रहा हूं कि मोंगोडीबी में कुल मिलाकर यूनियन कैसे करें। चलो निम्नलिखित दस्तावेज़ इमेजिंग एक संग्रह में (संरचना उदाहरण के लिए है):mongoDB

{ 
    linkedIn: { 
    people : [ 
    { 
     name : 'Fred' 
    }, 
    { 
     name : 'Matilda' 
    } 
    ] 
    }, 
    twitter: { 
    people : [ 
    { 
     name : 'Hanna' 
    }, 
    { 
     name : 'Walter' 
    } 
    ] 
    } 
} 

कैसे एक समग्र कि Twitter और LinkedIn में लोगों का संघ रिटर्न बनाने के लिए?

{ 
{ name :'Fred', source : 'LinkedIn'}, 
{ name :'Matilda', source : 'LinkedIn'}, 
{ name :'Hanna', source : 'Twitter'}, 
{ name :'Walter', source : 'Twitter'}, 
} 

उत्तर

12

इस के लिए दृष्टिकोण की एक जोड़ी है कि आप

db.collection.aggregate([ 
    // Assign an array of constants to each document 
    { "$project": { 
     "linkedIn": 1, 
     "twitter": 1, 
     "source": { "$cond": [1, ["linkedIn", "twitter"],0 ] } 
    }}, 

    // Unwind the array 
    { "$unwind": "$source" }, 

    // Conditionally push the fields based on the matching constant 
    { "$group": { 
     "_id": "$_id", 
     "data": { "$push": { 
      "$cond": [ 
       { "$eq": [ "$source", "linkedIn" ] }, 
       { "source": "$source", "people": "$linkedIn.people" }, 
       { "source": "$source", "people": "$twitter.people" } 
      ] 
     }} 
    }}, 

    // Unwind that array 
    { "$unwind": "$data" }, 

    // Unwind the underlying people array 
    { "$unwind": "$data.people" }, 

    // Project the required fields 
    { "$project": { 
     "_id": 0, 
     "name": "$data.people.name", 
     "source": "$data.source" 
    }} 
]) 
के लिए aggregate विधि का उपयोग कर सकते हैं 10

या MongoDB 2.6 से कुछ ऑपरेटरों का उपयोग कर एक अलग दृष्टिकोण के साथ:

db.people.aggregate([ 
    // Unwind the "linkedIn" people 
    { "$unwind": "$linkedIn.people" }, 

    // Tag their source and re-group the array 
    { "$group": { 
     "_id": "$_id", 
     "linkedIn": { "$push": { 
      "name": "$linkedIn.people.name", 
      "source": { "$literal": "linkedIn" } 
     }}, 
     "twitter": { "$first": "$twitter" } 
    }}, 

    // Unwind the "twitter" people 
    { "$unwind": "$twitter.people" }, 

    // Tag their source and re-group the array 
    { "$group": { 
     "_id": "$_id", 
     "linkedIn": { "$first": "$linkedIn" }, 
     "twitter": { "$push": { 
      "name": "$twitter.people.name", 
      "source": { "$literal": "twitter" } 
     }} 
    }}, 

    // Merge the sets with "$setUnion" 
    { "$project": { 
     "data": { "$setUnion": [ "$twitter", "$linkedIn" ] } 
    }}, 

    // Unwind the union array 
    { "$unwind": "$data" }, 

    // Project the fields 
    { "$project": { 
     "_id": 0, 
     "name": "$data.name", 
     "source": "$data.source" 
    }} 
]) 

और निश्चित रूप से आप बस परवाह नहीं करता है, तो क्या स्रोत था:

db.collection.aggregate([ 
    // Union the two arrays 
    { "$project": { 
     "data": { "$setUnion": [ 
      "$linkedIn.people", 
      "$twitter.people" 
     ]} 
    }}, 

    // Unwind the union array 
    { "$unwind": "$data" }, 

    // Project the fields 
    { "$project": { 
     "_id": 0, 
     "name": "$data.name", 
    }} 

]) 
2

सुनिश्चित नहीं हैं कि ऑपरेशन के उस तरह के लिए करता है, तो कुल का उपयोग कर एक से अधिक की सिफारिश की है नक्शे-कम हो लेकिन अगले आप जो चाह रहे हैं क्या कर रहा है (पता $ स्थिरांक में बिल्कुल भी कोई समस्या नहीं के साथ इस्तेमाल किया जा सकता है, तो .aggregate() फंक्शन):

aggregate([ 
    { $project: { linkedIn: '$linkedIn', twitter: '$twitter', idx: { $const: [0,1] }}}, 
    { $unwind: '$idx' }, 
    { $group: { _id : '$_id', data: { $push: { $cond:[ {$eq:['$idx', 0]}, { source: {$const: 'LinkedIn'}, people: '$linkedIn.people' } , { source: {$const: 'Twitter'}, people: '$twitter.people' } ] }}}}, 
    { $unwind: '$data'}, 
    { $unwind: '$data.people'}, 
    { $project: { _id: 0, name: '$data.people.name', source: '$data.source' }} 
])