सबसे पहले, Mongo map/reduce को एक क्वेरी टूल के रूप में उपयोग करने के लिए डिज़ाइन नहीं किया गया है (जैसा कि यह CouchDB में है), यह आपके लिए पृष्ठभूमि कार्यों को चलाने के लिए डिज़ाइन है। मैं ट्रैफ़िक डेटा का विश्लेषण करने के लिए काम पर इसका उपयोग करता हूं।
हालाँकि आप जो गलत कर रहे हैं वह यह है कि आप अपने इनपुट में सॉर्ट () लागू कर रहे हैं, लेकिन यह बेकार है क्योंकि जब map()
चरण पूरा हो गया है मध्यवर्ती दस्तावेज़ प्रत्येक keys
. द्वारा क्रमबद्ध हैं . चूंकि आपकी कुंजी एक दस्तावेज़ है, इसलिए इसे product_id
. द्वारा क्रमबद्ध किया जा रहा है , popularity
.
इस तरह मैंने अपना डेटासेट जेनरेट किया
function generate_dummy_data() {
for (i=2; i < 1000000; i++) {
db.foobar.save({
_id: i,
category_id: parseInt(Math.random() * 30),
popularity: parseInt(Math.random() * 50)
})
}
}
और यह मेरा नक्शा/कार्य कम करें:
var data = db.runCommand({
'mapreduce': 'foobar',
'map': function() {
emit({
sorting: this.popularity * -1,
product_id: this._id,
popularity: this.popularity,
}, 1);
},
'reduce': function(key, values) {
var sum = 0;
values.forEach(function(v) {
sum += v;
});
return sum;
},
'query': {category_id: 20},
'out': {inline: 1},
});
और यह अंतिम परिणाम है (इसे यहां पेस्ट करने में बहुत लंबा समय):
http://cesarodas.com/results.txt
यह काम करता है क्योंकि अब हम sorting, product_id, popularity
. द्वारा सॉर्ट कर रहे हैं . आप अपनी पसंद के अनुसार छँटाई के साथ खेल सकते हैं बस याद रखें कि अंतिम छँटाई keys
. द्वारा होती है आप पर ध्यान दिए बिना कि आपका इनपुट कैसे क्रमबद्ध किया जाता है।
वैसे भी जैसा कि मैंने पहले कहा था कि आपको मानचित्र के साथ प्रश्न पूछने से बचना चाहिए/इसे पृष्ठभूमि प्रसंस्करण के लिए डिज़ाइन किया गया था। अगर मैं आप होते तो मैं अपने डेटा को इस तरह से डिजाइन करता कि मैं इसे सरल प्रश्नों के साथ एक्सेस कर सकता हूं, इस मामले में हमेशा एक ट्रेड-ऑफ होता है जिसमें सरल प्रश्न रखने के लिए जटिल इंसर्ट/अपडेट होते हैं (इस तरह मैं MongoDB देखता हूं)।