2011-06-27 17 views
9

मैं अपने ब्लॉग प्लेटफार्म के लिए मोंगोडब का उपयोग करता हूं, जहां उपयोगकर्ता अपने ब्लॉग बना सकते हैं। सभी ब्लॉगों की सभी प्रविष्टियां एक प्रविष्टि संग्रह में हैं। प्रत्येक ब्लॉग के लिएमोंगोडब: प्रत्येक समूह से शीर्ष एन पंक्तियों का चयन करें

{ 
    'blog_id':xxx, 
    'timestamp':xxx, 
    'title':xxx, 
    'content':xxx 
} 

सवाल कहते हैं, वहाँ का चयन करने, कहते हैं किसी भी तरह से है, पिछले 3 प्रविष्टियों: एक प्रवेश के दस्तावेज़ की तरह दिखता है?

उत्तर

1

बुनियादी मोंगो में यह करने के लिए अगर आप दो चीजों के साथ रह सकते हैं एक ही रास्ता:

  • अपनी प्रविष्टि दस्तावेज़ में एक अतिरिक्त क्षेत्र, चलो यह कॉल "उम्र"
  • एक नया ब्लॉग प्रविष्टि किसी लेने अतिरिक्त अद्यतन

यदि हां, तो यहाँ तुम कैसे करते है:

  1. एक ne बनाने पर डब्ल्यू परिचय अपने सामान्य सम्मिलित करें और फिर सभी पदों की उम्र बढ़ाने के लिए इस अद्यतन को निष्पादित करें (जिसमें आपने अभी इस ब्लॉग के लिए डाला है):

    db.entries.update ({blog_id: BLOG_ID}, {आयु: { $ इंक: 1}}, झूठे सच)

  2. जब से क्वेरी, निम्न क्वेरी जो प्रत्येक ब्लॉग के लिए सबसे हाल ही में 3 प्रविष्टियों वापस आ जाएगी का उपयोग करें: {उम्र

    db.entries.find (: {$ LTE: 3}, टाइमस्टैम्प: {$ gte: STARTOFMONTH, $ lt:। ENDOFMONTH}}) प्रकार ({blog_id: 1, उम्र: 1})

ध्यान दें कि यह समाधान वास्तव में समेकन सुरक्षित है (डुप्लिकेट आयु के साथ कोई प्रविष्टि नहीं)।

+0

अपना विचार मिला। मैंने ऐसा कुछ भी नहीं सोचा था। एक नई पोस्ट बनाते समय एक अतिरिक्त अपडेट कोई समस्या नहीं होगी। हालांकि जब उपयोगकर्ता एक पोस्ट हटा देता है तो हमें अन्य सभी पदों के 'आयु' फ़ील्ड को अपडेट करना होगा। यह अद्यतन तब तक सीमित हो सकता है जब हटाए गए पोस्ट में 'आयु' <= 3 हो। क्या मुझे कुछ याद आ रही है? – Tacaza

+0

हां आपको उस अद्यतन को आयु <3 तक सीमित नहीं करना चाहिए क्योंकि आप डुप्लिकेट आयु के साथ समाप्त हो जाएंगे। इन-प्लेस अपडेट बेहद तेज़ हैं इसलिए यह कोई समस्या नहीं होनी चाहिए। एक डिलीट का अर्थ है प्रविष्टि को हटाना और आयु को 1 से कम करना जहां उम्र> delete_post.age। सौभाग्य। –

+0

यह बिल्कुल समझ में आता है। तुम्हारे सुझाव के लिए धन्यवाद! – Tacaza

0

समूह (एकत्रीकरण) के साथ यह संभव है, लेकिन यह एक पूर्ण-तालिका स्कैन बनाएगा।

क्या आपको वास्तव में बिल्कुल 3 की आवश्यकता है या आप सीमा निर्धारित कर सकते हैं ... उदा .: पिछले सप्ताह/महीने से अधिकतम 3 पद?

+0

आदर्श रूप में मैं वास्तव में 3 का चयन करना चाहते हैं, लेकिन पिछले महीने से अधिकतम 3 पदों काफी अच्छा हो सकता है अगर मैं डेटा असमान्यीकरण को छोड़कर एक समाधान नहीं मिल रहा। क्या आप मुझे उदाहरण दे सकते हैं कि यह कैसे किया जा सकता है? सभी mongodb के मानचित्र से मैंने पढ़ा है ट्यूटोरियल कम करें वे केवल आंकड़े (एकत्रीकरण) की गणना करने के लिए दिखाते हैं ... – Tacaza

1

एक और सवाल से उपयोग कर नक्शा को कम drcosta द्वारा इस उत्तर चाल

In mongo, how do I use map reduce to get a group by ordered by most recent

mapper = function() { 
    emit(this.category, {top:[this.score]}); 
} 

reducer = function (key, values) { 
    var scores = []; 
    values.forEach(
    function (obj) { 
     obj.top.forEach(
     function (score) { 
      scores[scores.length] = score; 
     }); 
    }); 
    scores.sort(); 
    scores.reverse(); 
    return {top:scores.slice(0, 3)}; 
} 

function find_top_scores(categories) { 
    var query = []; 
    db.top_foos.find({_id:{$in:categories}}).forEach(
    function (topscores) { 
     query[query.length] = { 
     category:topscores._id, 
     score:{$in:topscores.value.top} 
     }; 
    }); 
    return db.foo.find({$or:query}); 
8

आप पहली बार blog_id और timestamp क्षेत्रों से संग्रह में दस्तावेजों को सॉर्ट करने की जरूरत थी, एक प्रारम्भिक करना समूह जो अवरोही क्रम में मूल दस्तावेजों की एक सरणी बनाता है। इसके बाद आप पहले 3 तत्वों को वापस करने के लिए दस्तावेज़ों के साथ सरणी को टुकड़ा कर सकते हैं।

अंतर्ज्ञान इस उदाहरण में पीछा किया जा सकता है:

db.entries.aggregate([ 
    { '$sort': { 'blog_id': 1, 'timestamp': -1 } }, 
    {  
     '$group': { 
      '_id': '$blog_id', 
      'docs': { '$push': '$$ROOT' }, 
     } 
    }, 
    { 
     '$project': { 
      'top_three': { 
       '$slice': ['$docs', 3] 
      } 
     } 
    } 
]) 
+0

धन्यवाद, शानदार –

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