2015-11-01 6 views
6

का उपयोग करके प्रत्येक समूह को mongoDB में सीमित और क्रमबद्ध करें मैं प्रत्येक समूह को mongoDB में कैसे क्रमबद्ध और सीमित कर सकता हूं।एग्रीगेशन

डेटा नीचे पर विचार करें:

Country:USA,name:xyz,rating:10,id:x 
Country:USA,name:xyz,rating:10,id:y 
Country:USA,name:xyz,rating:10,id:z 
Country:USA,name:abc,rating:5,id:x 
Country:India,name:xyz,rating:5,id:x 
Country:India,name:xyz,rating:5,id:y 
Country:India,name:abc,rating:10,id:z 
Country:India,name:abc,rating:10,id:x 

अब कहते हैं कि मैं देश से समूह और प्रकार रेटिंग के द्वारा होगा और से प्रत्येक समूह के डेटा की सीमा 2.

तो जवाब होगा:

Country:USA 
name:xyz,rating:10,id:x 
name:xyz,rating:10,id:y 
Country:India 
name:abc,rating:10,id:x 
name:abc,rating:10,id:z 

मैं केवल समग्र ढांचे का उपयोग करके इसे पूरा करना चाहता हूं।

मैंने रेटिंग के लिए कुल मिलाकर क्रमबद्ध करने का प्रयास किया लेकिन बस पूछताछ के बाद कोई परिणाम नहीं निकलता।

उत्तर

9

आपका सबसे अच्छा विकल्प यहां प्रत्येक "देश" (आदर्श रूप से समानांतर) के लिए अलग-अलग प्रश्नों को चलाने और संयुक्त परिणामों को वापस करने के लिए है। प्रश्न काफी सरल हैं, और रेटिंग मान पर एक प्रकार को लागू करने के बाद केवल शीर्ष 2 मान वापस लौटें और पूर्ण परिणाम प्राप्त करने के लिए आपको कई प्रश्नों को करने की आवश्यकता होने पर भी तेज़ी से निष्पादित किया जाएगा।

समेकन ढांचा इस के लिए अब और यहां तक ​​कि निकट भविष्य में भी उपयुक्त नहीं है। समस्या यह है कि ऐसा कोई ऑपरेटर नहीं है जो किसी भी समूह के किसी भी तरह के परिणाम को "सीमा" देता है। तो ऐसा करने के लिए, आपको मूल रूप से $push सभी सामग्री को सरणी में और उस से "शीर्ष एन" मान निकालने की आवश्यकता है।

ऐसा करने के लिए आवश्यक वर्तमान संचालन बहुत भयानक हैं, और मूल समस्या यह है कि अधिकांश वास्तविक डेटा स्रोतों पर प्रति दस्तावेज़ 16 एमबी की बीएसओएन सीमा से अधिक होने की संभावना है।

इसके अलावा n जटिलता भी है जिसके कारण आपको इसे अभी करना होगा। लेकिन सिर्फ 2 आइटम के साथ प्रदर्शित करने के लिए:

db.collection.aggregate([ 
    // Sort content by country and rating 
    { "$sort": { "Country": 1, "rating": -1 } }, 

    // Group by country and push all items, keeping first result 
    { "$group": { 
     "_id": "$Country", 
     "results": { 
      "$push": { 
       "name": "$name", 
       "rating": "$rating", 
       "id": "$id" 
      } 
     }, 
     "first": { 
      "$first": { 
       "name": "$name", 
       "rating": "$rating", 
       "id": "$id" 
      } 
     } 
    }}, 

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

    // Remove the seen result from the array 
    { "$redact": { 
     "$cond": { 
      "if": { "$eq": [ "$results.id", "$first.id" ] }, 
      "then": "$$PRUNE", 
      "else": "$$KEEP" 
     } 
    }}, 

    // Group to return the second result which is now first on stack 
    { "$group": { 
     "_id": "$_id", 
     "first": { "$first": "$first" }, 
     "second": { 
      "$first": { 
       "name": "$results.name", 
       "rating": "$results.rating", 
       "id": "$results.id" 
      } 
     } 
    }}, 

    // Optionally put these in an array format 
    { "$project": { 
     "results": { 
      "$map": { 
       "input": ["A","B"], 
       "as": "el", 
       "in": { 
        "$cond": { 
         "if": { "$eq": [ "$$el", "A" ] }, 
         "then": "$first", 
         "else": "$second" 
        } 
       } 
      } 
     } 
    }} 
]) 

परिणाम हो जाता है लेकिन इसकी नहीं एक महान दृष्टिकोण और उच्च सीमा या यहां तक ​​कि जहां समूहों संभवतः n से कम परिणाम कुछ में वापस जाने के लिए है के लिए पुनरावृत्तियों के साथ एक बहुत अधिक जटिल हो जाता है यही कारण है कि मामलों।

वर्तमान विकास श्रृंखला (3.1.x) लेखन के रूप में एक $slice ऑपरेटर इस में थोड़ा और अधिक सरल बनाता है, लेकिन अभी भी एक ही "आकार" ख़तरा है:

db.collection.aggregate([ 
    // Sort content by country and rating 
    { "$sort": { "Country": 1, "rating": -1 } }, 

    // Group by country and push all items, keeping first result 
    { "$group": { 
     "_id": "$Country", 
     "results": { 
      "$push": { 
       "name": "$name", 
       "rating": "$rating", 
       "id": "$id" 
      } 
     } 
    }}, 
    { "$project": { 
     "results": { "$slice": [ "$results", 2 ] } 
    }} 
]) 

लेकिन मूल रूप से एकत्रीकरण तक ढांचे के पास $push या इसी तरह के समूह "सीमा" ऑपरेटर द्वारा उत्पादित वस्तुओं की संख्या को सीमित करने का कोई तरीका है, फिर समेकन ढांचा वास्तव में इस प्रकार की समस्या के लिए इष्टतम समाधान नहीं है।

इस तरह सरल प्रश्नों:

db.collection.find({ "Country": "USA" }).sort({ "rating": -1 }).limit(1) 

धागे की घटना पाश से समानांतर प्रसंस्करण में प्रत्येक विशिष्ट देश के लिए भागो और आदर्श रूप से संयुक्त परिणाम के साथ सबसे इष्टतम दृष्टिकोण अभी पैदा करता है। वे केवल वही चीज प्राप्त करते हैं जो आवश्यक है, जो कि बड़ी समस्या है कि समेकन ढांचा अभी तक इस तरह के समूह में संभाल नहीं सकता है।

तो इस "संयुक्त क्वेरी परिणाम" को अपनी चुनी भाषा के लिए सबसे इष्टतम तरीके से करने के लिए समर्थन की तलाश करें, क्योंकि यह समेकन ढांचे पर इसे फेंकने से कहीं अधिक जटिल और अधिक प्रदर्शनकारी होगा।

+0

आपके विस्तृत उत्तर के लिए धन्यवाद। ऐसा लगता है कि मैं अंतिम विकल्प के साथ जा रहा हूं जो कार्यान्वित करना आसान है और सबसे इष्टतम है। –

+0

@ वैट गंधी यह विचार है। यह कैसे किया जा सकता है इसका उदाहरण वास्तव में केवल उन समस्याओं का प्रदर्शन करना है जो हो सकती हैं। अलग-अलग प्रश्नों को यह उन समस्याओं के बिना किया जाता है। –

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