2011-08-16 2 views
6

* असल में मैं आखिरी घंटे में अपने स्कोर द्वारा वस्तुओं को ऑर्डर करने का प्रयास कर रहा हूं।MongoDB MapReduce स्थान पर अपडेट करें

मैं अपने डेटाबेस में ऑब्जेक्ट्स के लिए एक घंटे के वोट राशि उत्पन्न करने की कोशिश कर रहा हूं। वोट प्रत्येक वस्तु में एम्बेडेड हैं। वस्तु स्कीमा इस तरह दिखता है:

{ 
    _id: ObjectId 
    score: int 
    hourly-score: int <- need to update this value so I can order by it 
    recently-voted: boolean 
    votes: { 
     "4e4634821dff6f103c040000": { <- Key is __toString of voter ObjectId 
      "_id": ObjectId("4e4634821dff6f103c040000"), <- Voter ObjectId 
      "a": 1, <- Vote amount 
      "ca": ISODate("2011-08-16T00:01:34.975Z"), <- Created at MongoDate 
      "ts": 1313452894 <- Created at timestamp 
     }, 
     ... repeat ... 
    } 
} 

यह सवाल वास्तव में एक प्रश्न से संबंधित है मैं Best way to model a voting system in MongoDB

कुछ दिनों के लिए कहा पहले मैं कैसे (मैं कर सकते हैं?) के बाद करने के लिए एक MapReduce आदेश चला जाएगा :

  1. केवल के साथ वस्तुओं पर चलने हाल ही में मतदान = true या प्रति घंटा स्कोर> 0.
  2. पिछले एक घंटे में बनाए वोट की राशि की गणना।
  3. प्रति घंटा-स्कोर = ऊपर गणना की गई राशि अपडेट करें, और हाल ही में मतदान = झूठी।

मैं भी here कि मैं db.getMongo चलाकर गुलाम डीबी पर एक MapReduce प्रदर्शन कर सकते हैं पढ़ा()। SetSlaveOk() एम/आर आदेश से पहले। क्या मैं दास पर कमी चला सकता हूं और मास्टर डीबी अपडेट कर सकता हूं?

मोंगो MapReduce के साथ इन-प्लेस अपडेट भी संभव हैं?

उत्तर

10

आप निश्चित रूप से ऐसा कर सकते हैं। मैं आपके प्रश्नों को एक समय में संबोधित करूंगा:

1. आप अपने मानचित्र-कम के साथ एक क्वेरी निर्दिष्ट कर सकते हैं, जो वस्तुओं के सेट को फ़िल्टर करता है जो मानचित्र चरण में पारित किया जाएगा। मोंगो खोल में, इस तरह (m संभालने और r अपने नक्शाकार और कम करने कार्यों के नाम क्रमशः) दिखेगा:

> db.coll.mapReduce(m, r, {query: {$or: [{"recently-voted": true}, {"hourly-score": {$gt: 0}}]}}) 

2. चरण # 1 आप के साथ सभी दस्तावेजों पर अपने नक्शाकार का उपयोग करने देगा पिछले घंटे में कम से कम एक वोट (या recently-voted के साथ सत्य पर सेट), लेकिन सभी वोट पिछले घंटे में नहीं होंगे।

function m() { 
    var hour_ago = new Date() - 3600000; 
    this.votes.forEach(function (vote) { 
    if (vote.ts > hour_ago) { 
     emit(/* your key */, this.vote.a); 
    } 
    }); 
} 

और कम करने के लिए:: तो आप अपने नक्शाकार में सूची फिल्टर करने के लिए, और केवल फेंकना उन वोट की आवश्यकता होगी आप गिनती करना चाहते हैं

function r(key, values) { 
    var sum = 0; 
    values.forEach(function(value) { sum += value; }); 
    return sum; 
} 

3. प्रति घंटा स्कोर तालिका अद्यतन करने के लिए , आप मानचित्र-कम करने के लिए reduceOutput विकल्प का उपयोग कर सकते हैं, जो आपके रेड्यूसर को उत्सर्जित मानों और आउटपुट संग्रह में पहले से सहेजे गए मान, (यदि कोई हो) के साथ कॉल करेगा। उस पास का परिणाम आउटपुट संग्रह में सहेजा जाएगा। यह लगता है कि:

> db.coll.mapReduce(m, r, {query: ..., out: {reduce: "output_coll"}}) 

इसके अलावा करने के लिए फिर से कम करने के उत्पादन, आप merge उपयोग कर सकते हैं जो नव निर्मित लोगों के साथ उत्पादन संग्रह में दस्तावेजों के ऊपर लिख देगा (लेकिन एक _id अलग से किसी भी दस्तावेज को पीछे छोड़ से _id रों बनाया आपके एमआर जॉब द्वारा), replace, जो प्रभावी रूप से एक ड्रॉप-एंड-निर्माण ऑपरेशन है और डिफ़ॉल्ट है, या {inline: 1} का उपयोग करें, जो परिणाम सीधे खोल या आपके ड्राइवर को वापस कर देगा। ध्यान दें कि {inline: 1} का उपयोग करते समय, आपके परिणाम एक दस्तावेज़ के लिए अनुमत आकार में फिट होना चाहिए (हाल ही में मोंगोडीबी रिलीज में 16 एमबी)।

(4.) आप चला सकते हैं द्वितीयक पर नौकरियों नक्शे-कम करने ("दास"), लेकिन जब से द्वितीयक राईट स्वीकार नहीं कर सकते (है कि क्या उन्हें माध्यमिक बनाता है), तो आप केवल इस इनलाइन उत्पादन का उपयोग कर सकते हैं।

+1

ठीक है सब कुछ चरण 3 तक समझ में आता है। मुझे समझ में नहीं आता कि कम घंटे के स्कोर योग को कैसे लेना है और संग्रह में प्रासंगिक वस्तुओं को अपडेट करना है। मान लें कि हमारे पास मेरे प्रश्न में स्कीमा के साथ एक संग्रह टिप्पणियां हैं और मैं सभी कम प्रासंगिक टिप्पणियों को घंटे-स्कोर को नए कम रकम में अपडेट करना चाहता हूं। प्रति घंटा स्कोर टिप्पणी वस्तुओं पर एक पैरामीटर है, एक अलग संग्रह में कुछ नहीं। मुझे यह कैसे करना है? – Marc

+0

ओह, मैं देखता हूं - आप मानचित्र-आउटपुट के आउटपुट के साथ 'घंटा-स्कोर' फ़ील्ड को वोट राशियों (फ़ील्ड 'वोट.ए') के योग के रूप में अपडेट करना चाहते हैं? मुझे नहीं लगता कि आप मानचित्र-कम के साथ इन लाइन को कर सकते हैं, लेकिन आप निश्चित रूप से एक पोस्ट-प्रोसेसिंग चरण कर सकते हैं जो मानचित्र को कम करता है-किसी भी संग्रह को अपडेट करने के लिए आउटपुट को कम करता है। – dcrosta

+0

हम्म ठीक है। एक रिलेशनल डेटाबेस से यह एक काफी सरल काम है। असल में मैं बस इतना करना चाहता हूं कि आखिरी घंटे में ऑब्जेक्ट्स ऑर्डर करें। एक रिलेशनल में मैं स्कोर को एक अलग टेबल में रखूंगा। फिर मैं ऑब्जेक्ट टेबल से चयन करता हूं, स्कोर टेबल में शामिल होता हूं, उस योग के आखिरी घंटे और ऑर्डर के स्कोर देता हूं। शायद या तो ए। मोंगो बस या बी के लिए अच्छा नहीं है। मैं अपनी वस्तुओं/वोटों को गलत तरीके से व्यवस्थित कर रहा हूं? – Marc