2012-10-24 7 views
7

क्या किसी सरणी के विशिष्ट तत्व द्वारा समूह में समेकन ढांचे का उपयोग करना संभव है?मोंगो एकत्रीकरण ढांचे के साथ सरणी के विशिष्ट तत्व द्वारा समूह

इस तरह दस्तावेजों के साथ इस तरह की है कि:

{ 
    name: 'Russell', 
    favourite_foods: [ 
    { name: 'Pizza', type: 'Four Cheeses' }, 
    { name: 'Burger', type: 'Veggie'} 
    ], 
    height: 6 
} 

मैं शीर्ष पसंदीदा भोजन की एक अलग सूची मिल सकता है (यानी सूचकांक 0 में खाद्य पदार्थ।) जो शीर्ष पसंदीदा भोजन है कि सबसे ऊंची व्यक्ति की ऊंचाई के साथ ?

कुछ इस तरह (हालांकि यह सरणी सूचकांक पहुँच डॉट नोटेशन के रूप में काम नहीं करता है एकत्रीकरण ढांचे में काम करने के लिए प्रतीत नहीं होता है):

db.people.aggregate([ 
    { $group : { _id: "$favourite_foods.0.name", max_height: { $max : "$height" } } } 
]) 

उत्तर

5

ऐसा लगता है कि यह नहीं वर्तमान में निकालने के लिए संभव है एकत्रीकरण में एक सरणी से किसी विशिष्ट तत्व: https://jira.mongodb.org/browse/SERVER-4589

+0

हाँ, मैंने इसे देखा। मुझे उम्मीद है कि कोई कामकाज के साथ आया था ... – Russell

+0

आप स्थिति के आधार पर एक मनमाना तत्व निकालने नहीं कर सकते हैं, आपके पास पहले या आखिरी $ $ $ के साथ $ 1 या $ अंतिम ऑपरेटर के साथ $ 1 अनइंड और फिर से $ समूह प्राप्त करने का कोई तरीका होता है। –

+1

** अच्छी खबर **: उस मुद्दे को अंततः [$ arrayElementAt ऑपरेटर] (https://docs.mongodb.com/manual/reference/operator/aggregation/arrayElemAt/) – joeytwiddle

2

मुझे लगता है कि आप $ परियोजना का उपयोग कर सकते हैं और $ तनाव कम ऑपरेटरों (अगर यह तुम क्या नहीं पूरा करने के लिए कोशिश कर रहे हैं मुझे पता है):

> db.people.aggregate(
    {$unwind: "$favourite_foods"}, 
    {$project: {food : "$favourite_foods", height: 1}}, 
    {$group : { _id: "$food", max_height: { $max : "$height" } } }) 


{ 
    "result" : [ 
     { 
      "_id" : { 
       "name" : "Burger", 
       "type" : "Veggie" 
      }, 
      "max_height" : 6 
     }, 
     { 
      "_id" : { 
       "name" : "Pizza", 
       "type" : "Four Cheeses" 
      }, 
      "max_height" : 6 
     } 
    ], 
    "ok" : 1 
} 

http://docs.mongodb.org/manual/applications/aggregation/

+0

के साथ हल किया गया था जिसमें पसंदीदा पर सभी खाद्य पदार्थ शामिल होंगे सूची, न केवल शीर्ष पर ... बर्गर इस बेहद छोटे डेटा सेट में किसी का भी शीर्ष विकल्प नहीं है :) –

+0

@asya सही है, मैं केवल सरणी – Russell

+0

दोह से पहला खाना चाहता हूं। मेरी गलती। अच्छा एक, अस्या। – Jenna

14

लगता है जैसे आप प्रत्येक व्यक्ति सरणी में पहले होने के लिए पसंदीदा भोजन पर निर्भर कर रहे हैं। यदि हां, तो एक समेकन ढांचा ऑपरेटर है जिसका आप लाभ उठा सकते हैं।

db.people.aggregate(
[ 
    { 
     "$unwind" : "$favourite_foods" 
    }, 
    { 
     "$group" : { 
      "_id" : { 
       "name" : "$name", 
       "height" : "$height" 
      }, 
      "faveFood" : { 
       "$first" : "$favourite_foods" 
      } 
     } 
    }, 
    { 
     "$group" : { 
      "_id" : "$faveFood.name", 
      "height" : { 
       "$max" : "$_id.height" 
      } 
     } 
    } 
]) 

इस नमूना डेटासेट पर::

> db.people.find().pretty() 
{ 
    "_id" : ObjectId("508894efd4197aa2b9490741"), 
    "name" : "Russell", 
    "favourite_foods" : [ 
     { 
      "name" : "Pizza", 
      "type" : "Four Cheeses" 
     }, 
     { 
      "name" : "Burger", 
      "type" : "Veggie" 
     } 
    ], 
    "height" : 6 
} 
{ 
    "_id" : ObjectId("5088950bd4197aa2b9490742"), 
    "name" : "Lucy", 
    "favourite_foods" : [ 
     { 
      "name" : "Pasta", 
      "type" : "Four Cheeses" 
     }, 
     { 
      "name" : "Burger", 
      "type" : "Veggie" 
     } 
    ], 
    "height" : 5.5 
} 
{ 
    "_id" : ObjectId("5088951dd4197aa2b9490743"), 
    "name" : "Landy", 
    "favourite_foods" : [ 
     { 
      "name" : "Pizza", 
      "type" : "Four Cheeses" 
     }, 
     { 
      "name" : "Pizza", 
      "type" : "Veggie" 
     } 
    ], 
    "height" : 5 
} 
{ 
    "_id" : ObjectId("50889541d4197aa2b9490744"), 
    "name" : "Augie", 
    "favourite_foods" : [ 
     { 
      "name" : "Sushi", 
      "type" : "Four Cheeses" 
     }, 
     { 
      "name" : "Pizza", 
      "type" : "Veggie" 
     } 
    ], 
    "height" : 6.2 
} 

आपको ये परिणाम मिलता है:

{ 
    "result" : [ 
     { 
      "_id" : "Pasta", 
      "height" : 5.5 
     }, 
     { 
      "_id" : "Pizza", 
      "height" : 6 
     }, 
     { 
      "_id" : "Sushi", 
      "height" : 6.2 
     } 
    ], 
    "ok" : 1 
} 
+0

यदि नाम अद्वितीय नहीं है तो आप पहले $ समूह में अपनी जगह में _id का उपयोग कर सकते हैं। –

+0

अच्छा समाधान, लेकिन यह उनके क्रमबद्ध क्रम को बनाए रखने के लिए उत्पादित दस्तावेजों पर निर्भर करता है - क्या आप इस पर भरोसा कर सकते हैं और क्या इसे कहीं कहीं दस्तावेज किया गया है? – Russell

+0

मुझे पता है कि यह कई परीक्षणों से कैसे काम करता है, और जब यह दस्तावेज़ों में नहीं है, तो मैंने सोर्स कोड को देखा और ऐसा लगता है कि यह मामला है। देखें: https://github.com/mongodb/mongo/blob/master/src/mongo/db/pipeline/document_source_unwind.cpp –

0

बस के बारे में अधिक जानकारी जोड़ने

यहाँ पाइपलाइन का उपयोग कर सकते है "$wind" का उपयोग करने के बाद परिणाम:


डाक्यूमेंट:

> db.people.find().pretty() 
{ 
    "_id" : ObjectId("508894efd4197aa2b9490741"), 
    "name" : "Russell", 
    "favourite_foods" : [ 
     { 
      "name" : "Pizza", 
      "type" : "Four Cheeses" 
     }, 
     { 
      "name" : "Burger", 
      "type" : "Veggie" 
     } 
    ], 
    "height" : 6 
}, 
... 


AGGREAGATION:

db.people.aggregate([{ 
    $unwind: "$favourite_foods" 
}]); 


परिणाम:

{ 
    "_id" : ObjectId("508894efd4197aa2b9490741"), 
    "name" : "Russell", 
    "favourite_foods" :{ 
      "name" : "Pizza", 
      "type" : "Four Cheeses" 
    }, 
    "height" : 6 
}, 
{ 
    "_id" : ObjectId("508894efd4197aa2b9490741"), 
    "name" : "Russell", 
    "favourite_foods" : { 
      "name" : "Burger", 
      "type" : "Veggie" 
    }, 
    "height" : 6 
} 


अलावा में:
अगर वहाँ एक संग्रह रिकॉर्ड, में दो से अधिक सरणी क्षेत्रों हम सरणी क्षेत्र निर्दिष्ट करने के लिए "$project" मंच का उपयोग कर सकते हैं।

db.people.aggregate([ 
    { 
     $project:{ 
      "favourite_foods": 1 
     } 
    }, 
    { 
     $unwind: "$favourite_foods" 
    } 
]); 
संबंधित मुद्दे