2013-10-11 5 views
6

मोंगोडीबी में, मैं मानचित्र-कम करने वाले कार्यों को लिखने की कोशिश कर रहा हूं जो कुछ मानदंडों को पूरा करते समय केवल डेटा बचाता है।मैं MongoDB में अपने कम() फ़ंक्शन में डेटा कैसे सहेजूं?

मैं अपने reducer से emit() नहीं समझ सकता। यह हमेशा डेटा, एक तरफ या किसी अन्य को बचाता है।

यहां एक सामान्य उदाहरण है। डेटा के संदर्भ को अनदेखा करें - मैंने इस प्रश्न के उद्देश्य के लिए पूरी तरह से यह डेटा और कोड बनाया है।

डेटा सेट:

{ "_id" : ObjectId("52583b3a58da9769dda48853"), "date" : "01-01-2013", "count" : 1 } 
{ "_id" : ObjectId("52583b3d58da9769dda48854"), "date" : "01-01-2013", "count" : 1 } 
{ "_id" : ObjectId("52583b4258da9769dda48855"), "date" : "01-02-2013", "count" : 1 } 
{ "_id" : ObjectId("52583b4f58da9769dda48856"), "date" : "01-03-2013", "count" : 4 } 

मानचित्र फंक्शन:

// Map all data by (date, count) 
var map = function() { 
    var key = this.date; 
    var value = this.count; 
    emit(key, value); 
} 

प्रसारण कि बस अवांछित डेटा पर ध्यान नहीं देता।

// Only save dates which have count > 2 
var reducer = function(date, counts) { 
    var sum = Array.sum(counts); 
    if (sum > 2) { 
     return sum; 
    } 
} 

परिणाम (1 के मूल्य को नजरअंदाज नहीं किया गया था):

{ "_id" : "01-01-2013", "value" : null } 
{ "_id" : "01-02-2013", "value" : 1 } 
{ "_id" : "01-03-2013", "value" : 4 } 

मैं भी एक खाली वापसी बयान में जोड़ा है, लेकिन एक ही परिणाम मिल गया:

// Only save dates which have count > 2 
var reducer = function(date, counts) { 
    var sum = Array.sum(counts); 
    if (sum > 2) { 
     return sum; 
    } 
    else return; 
} 

मैं चाहते हैं क्या ऐसा होने के लिए मैप-कमी चलाने के बाद ही मेरे आउटपुट संग्रह में निम्न डेटा मौजूद होगा। मैं इसे कैसे पूरा कर सकता हूं?

{ "_id" : "01-03-2013", "value" : 4 } 

उत्तर

3

आप नीचे दिए गए कार्यों के साथ एक अतिरिक्त MapReduce आपरेशन चला सकते हैं,।

तो, इतना की तरह MapReduce चल:

db.map_reduce_example.mapReduce(
    second_map, second_reduce, {out: 'final_mapreduce_result'}); 

निम्नलिखित संग्रह का उत्पादन करेगा:

> db.final_mapreduce_result.find() 
{ "_id" : "01-03-2013", "value" : 4 } 

नोट यदि आप इस दृष्टिकोण का उपयोग करने का फैसला, तो आप से if (sum > 2) हालत निकाल सकते हैं कि पहले समारोह को कम करें।

+0

यह चालाक है! मुझे यह देखने के लिए एक रन देना होगा कि मेरे वास्तविक डेटा पर कितनी जल्दी चलती है लेकिन लक्ष्य को पूरा करने के लिए यह एक बहुत अच्छी चाल है। धन्यवाद। – Kurtis

+3

यदि आप कुछ परिणाम फ़िल्टर करना चाहते हैं तो मैं नक्शा/कम नहीं करता। पहले मानचित्र/कम करने के बाद बस हटाएं: db.mroutput.remove ({value: {$ lte: 2}})। निकालें() मानचित्र/कम से कम तेज़ी से चलाएगा। –

+0

@RobMoore आप सही हैं; यह एक आसान और संभावित रूप से अधिक कुशल समाधान है। मुझे लगता है कि आपको इसे एक अलग उत्तर के रूप में पोस्ट करना चाहिए। – GolfWolf

2

हमें याद है कि एक कम करने के लिए अगर वहाँ कुंजी (मानचित्र() से) केवल 1 उत्सर्जित मूल्य है छोड़ा जा सकता है की जरूरत है। हमें परिणामों को कम करने में भी फ़िल्टर करने की कोशिश नहीं करनी चाहिए क्योंकि कम से कम एक ही कुंजी के लिए कई बार कॉल किया जा सकता है (प्रत्येक बार उत्सर्जित मानों के सबसेट के साथ)।

एकमात्र अन्य विकल्प अंतिम तरीका है लेकिन परिणामस्वरूप नल मान परिणाम से प्रविष्टियों को हटाने नहीं देंगे।

मुझे लगता है कि परिणाम प्राप्त करने का एकमात्र तरीका नक्शा कम करने के बजाय एकत्रीकरण ढांचे का उपयोग करना है। पाइपलाइन लगेगा जैसे:

db.test.aggregate( 
    { 
    "$project" : { 
     "_id" : 0, 
     "date" : 1, 
     "count" : 1 
    } 
    }, 
    { 
    "$group" : { 
     "_id" : "$date", 
     "value" : { "$sum" : "$count" } 
    } 
    }, 
    { 
    "$match" : { 
     "value" : { "$gt" : 2 } 
    } 
    } 
); 
{ "result" : [ { "_id" : "01-03-2013", "value" : 4 } ], "ok" : 1 } 

इस दृष्टिकोण को ही प्रमुख नीचे की ओर परिणामों को वापस इनलाइन जो 16MB करने के लिए परिणाम के आकार को सीमित आना है। 2.6 रिलीज में इसे ठीक/उपचार किया जाएगा: https://jira.mongodb.org/browse/SERVER-10097

एचटीएच, रॉब। क्योंकि not having multiple values per key will cause it to not even be called इस मामले में

var second_map = function() { 
    if(this.value > 2) { 
     emit(this._id, this.value); 
    } 
} 

और

var second_reduce = function() {} 

को कम समारोह खाली हो सकता है,:

+0

मुख्य बात जो मुझे एग्रीगेशन फ्रेमवर्क के बारे में पसंद नहीं है वह आउटपुट प्रारूप है। यह सभी परिणाम लेता है और इसे एक ही वस्तु में संग्रहीत करता है। मैं निश्चित रूप से सुझाव की सराहना करता हूं, यद्यपि! और यह जानकर कि 16 एमबी सीमा जल्द ही तय की जाएगी, यह भी अच्छी खबर है। धन्यवाद! – Kurtis

+2

2.5.2 (देव रिलीज) पहले से ही इस कार्यान्वित किया गया है - एकत्रीकरण ढांचा एक कर्सर वापस लौटा सकता है, या आप आउटपुट निर्दिष्ट कर सकते हैं संग्रह पर जाएं। समेकन ढांचे को ध्यान में रखते हुए मानचित्र-कमी से बहुत तेज़ है, मैं आपको जब भी कर सकता हूं इसका उपयोग करने के लिए प्रोत्साहित करता हूं। –

+1

इसके अतिरिक्त, यदि आपको MapReduce के लिए यह होना है, तो https://jira.mongodb.org/browse/SERVER-2340 के लिए वोट दें जो इस सुविधा का अनुरोध करता है। ऐसी चीजें हैं जो एजीजी फ्रेमवर्क नहीं कर सकती हैं, जो नक्शा कम कर सकता है, इसलिए यह अभी भी एक उपयोगी वृद्धि है। –

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