MongoDB
 sql >> डेटाबेस >  >> NoSQL >> MongoDB

MongoDB एकत्रीकरण - $ समूह तिथि के अनुसार भले ही मौजूद न हो

डेटाबेस को उस डेटा के लिए परिणाम वापस करने के लिए बाध्य करने की कोशिश करने के बजाय जो मौजूद नहीं है, क्वेरी के लिए रिक्त डेटा को बाहरी रूप से उत्पन्न करना और परिणामों को उनमें मर्ज करना एक बेहतर अभ्यास है। इस तरह आपके पास आपकी "0" प्रविष्टियाँ होती हैं जहाँ कोई डेटा नहीं होता है और डेटाबेस को जो है उसे वापस करने की अनुमति देता है।

विलय अद्वितीय कुंजी की हैश तालिका बनाने और उस हैश तालिका में एकत्रीकरण परिणामों में पाए गए किसी भी मान को बदलने की एक बुनियादी प्रक्रिया है। जावास्क्रिप्ट में एक मूल वस्तु अच्छी तरह से सूट करती है क्योंकि सभी कुंजियाँ अद्वितीय होती हैं।

मैं वास्तव में एक Date लौटाना भी पसंद करता हूं दिनांक गणित का उपयोग करके दिनांक एकत्रीकरण ऑपरेटरों का उपयोग करने के बजाय आवश्यक अंतराल पर तारीख को "गोल" करने के लिए दिनांक गणित का उपयोग करके एकत्रीकरण परिणामों से ऑब्जेक्ट। आप $subtract का इस्तेमाल करके तारीखों में फेरबदल कर सकते हैं युग दिनांक मान के साथ किसी अन्य तिथि से घटाकर मान को संख्यात्मक टाइमस्टैम्प प्रतिनिधित्व में बदलने के लिए, और $mod ऑपरेटर शेष प्राप्त करने के लिए और आवश्यक अंतराल के लिए दिनांक को गोल करें।

इसके विपरीत $add का उपयोग करके एक समान युग की तारीख वस्तु के साथ एक पूर्णांक मान को वापस बीएसओएन दिनांक में बदल देगा। और निश्चित रूप से इसे सीधे $group एक अलग $project का उपयोग करने के बजाय चरण के रूप में आप संशोधित तिथियों को सीधे समूह में संसाधित कर सकते हैं _id वैसे भी मूल्य।

शेल उदाहरण के रूप में:

var sample = 30,
    Days = 30,
    OneDay = ( 1000 * 60 * 60 * 24 ),
    now = Date.now(),
    Today = now - ( now % OneDay ) ,
    nDaysAgo = Today - ( OneDay * Days ),
    startDate = new Date( nDaysAgo ),
    endDate = new Date( Today + OneDay ),
    store = {};

var thisDay = new Date( nDaysAgo );
while ( thisDay < endDate ) {
    store[thisDay] = 0;
    thisDay = new Date( thisDay.valueOf() + OneDay );
}

db.datejunk.aggregate([
    { "$match": { "when": { "$gte": startDate } }},
    { "$group": {
        "_id": {
            "$add": [
                { "$subtract": [
                    { "$subtract": [ "$when", new Date(0) ] },
                    { "$mod": [
                        { "$subtract": [ "$when", new Date(0) ] },
                        OneDay
                    ]}
                ]},
                new Date(0)
            ]
        },
        "count": { "$sum": 1 }
    }}
]).forEach(function(result){
    store[result._id] = result.count;
});

Object.keys(store).forEach(function(k) {
    printjson({ "date": k, "count": store[k] })
});

जो 0 . सहित अंतराल में सभी दिन लौटाएगा वे मान जहां कोई डेटा मौजूद नहीं है, जैसे:

{ "date" : "Tue Sep 22 2015 10:00:00 GMT+1000 (AEST)", "count" : 0 }
{ "date" : "Wed Sep 23 2015 10:00:00 GMT+1000 (AEST)", "count" : 1 }
{ "date" : "Thu Sep 24 2015 10:00:00 GMT+1000 (AEST)", "count" : 0 }
{ "date" : "Fri Sep 25 2015 10:00:00 GMT+1000 (AEST)", "count" : 1 }
{ "date" : "Sat Sep 26 2015 10:00:00 GMT+1000 (AEST)", "count" : 1 }
{ "date" : "Sun Sep 27 2015 10:00:00 GMT+1000 (AEST)", "count" : 0 }
{ "date" : "Mon Sep 28 2015 10:00:00 GMT+1000 (AEST)", "count" : 1 }
{ "date" : "Tue Sep 29 2015 10:00:00 GMT+1000 (AEST)", "count" : 1 }
{ "date" : "Wed Sep 30 2015 10:00:00 GMT+1000 (AEST)", "count" : 0 }
{ "date" : "Thu Oct 01 2015 10:00:00 GMT+1000 (AEST)", "count" : 1 }
{ "date" : "Fri Oct 02 2015 10:00:00 GMT+1000 (AEST)", "count" : 2 }
{ "date" : "Sat Oct 03 2015 10:00:00 GMT+1000 (AEST)", "count" : 0 }
{ "date" : "Sun Oct 04 2015 11:00:00 GMT+1100 (AEST)", "count" : 1 }
{ "date" : "Mon Oct 05 2015 11:00:00 GMT+1100 (AEDT)", "count" : 0 }
{ "date" : "Tue Oct 06 2015 11:00:00 GMT+1100 (AEDT)", "count" : 1 }
{ "date" : "Wed Oct 07 2015 11:00:00 GMT+1100 (AEDT)", "count" : 2 }
{ "date" : "Thu Oct 08 2015 11:00:00 GMT+1100 (AEDT)", "count" : 2 }
{ "date" : "Fri Oct 09 2015 11:00:00 GMT+1100 (AEDT)", "count" : 1 }
{ "date" : "Sat Oct 10 2015 11:00:00 GMT+1100 (AEDT)", "count" : 1 }
{ "date" : "Sun Oct 11 2015 11:00:00 GMT+1100 (AEDT)", "count" : 1 }
{ "date" : "Mon Oct 12 2015 11:00:00 GMT+1100 (AEDT)", "count" : 0 }
{ "date" : "Tue Oct 13 2015 11:00:00 GMT+1100 (AEDT)", "count" : 3 }
{ "date" : "Wed Oct 14 2015 11:00:00 GMT+1100 (AEDT)", "count" : 2 }
{ "date" : "Thu Oct 15 2015 11:00:00 GMT+1100 (AEDT)", "count" : 2 }
{ "date" : "Fri Oct 16 2015 11:00:00 GMT+1100 (AEDT)", "count" : 0 }
{ "date" : "Sat Oct 17 2015 11:00:00 GMT+1100 (AEDT)", "count" : 3 }
{ "date" : "Sun Oct 18 2015 11:00:00 GMT+1100 (AEDT)", "count" : 0 }
{ "date" : "Mon Oct 19 2015 11:00:00 GMT+1100 (AEDT)", "count" : 0 }
{ "date" : "Tue Oct 20 2015 11:00:00 GMT+1100 (AEDT)", "count" : 0 }
{ "date" : "Wed Oct 21 2015 11:00:00 GMT+1100 (AEDT)", "count" : 2 }
{ "date" : "Thu Oct 22 2015 11:00:00 GMT+1100 (AEDT)", "count" : 1 }

यह ध्यान में रखते हुए कि सभी "तारीख" मान वास्तव में अभी भी बीएसओएन तिथियां हैं, लेकिन .printjson() से आउटपुट में बस उस तरह स्ट्रिंग करें शेल विधि के रूप में।

थोड़ा और संक्षिप्त उदाहरण nodejs . का उपयोग करके दिखाया जा सकता है जहां आप async.parallel जैसे कार्यों का उपयोग कर सकते हैं एक ही समय में हैश निर्माण और एकत्रीकरण क्वेरी दोनों को संसाधित करने के लिए, साथ ही nedb जो मोंगोडीबी संग्रह का उपयोग करने से परिचित कार्यों का उपयोग करके "हैश" लागू करता है। यह यह भी दिखाता है कि यदि आप .aggregate() से लौटे कर्सर की प्रोसेसिंग को स्ट्रीम प्रोसेसिंग में बदलते हैं तो यह वास्तविक MongoDB संग्रह का उपयोग करके बड़े परिणामों के लिए कैसे स्केल कर सकता है :

var async = require('async'),
    mongodb = require('mongodb'),
    MongoClient = mongodb.MongoClient,
    nedb = require('nedb'),
    DataStore = new nedb();

// Setup vars
var sample = 30,
    Days = 30,
    OneDay = ( 1000 * 60 * 60 * 24 ),
    now = Date.now(),
    Today = now - ( now % OneDay ) ,
    nDaysAgo = Today - ( OneDay * Days ),
    startDate = new Date( nDaysAgo ),
    endDate = new Date( Today + OneDay );

MongoClient.connect('mongodb://localhost/test',function(err,db) {

  var coll = db.collection('datejunk');

  async.series(
    [
      // Clear test collection
      function(callback) {
        coll.remove({},callback)
      },

      // Generate a random sample
      function(callback) {
        var bulk = coll.initializeUnorderedBulkOp();

        while (sample--) {
          bulk.insert({
            "when": new Date(
              Math.floor(
                Math.random()*(Today-nDaysAgo+OneDay)+nDaysAgo
              )
            )
          });
        }
        bulk.execute(callback);
      },

      // Aggregate data and dummy data
      function(callback) {
        console.log("generated");
        async.parallel(
          [
            // Dummy data per day
            function(callback) {
              var thisDay = new Date( nDaysAgo );
              async.whilst(
                function() { return thisDay < endDate },
                function(callback) {
                  DataStore.update(
                    { "date": thisDay },
                    { "$inc": { "count": 0 } },
                    { "upsert": true },
                    function(err) {
                      thisDay = new Date( thisDay.valueOf() + OneDay );
                      callback(err);
                    }
                  );
                },
                callback
              );
            },
            // Aggregate data in collection
            function(callback) {
              coll.aggregate(
                [
                  { "$match": { "when": { "$gte": startDate } } },
                  { "$group": {
                    "_id": {
                      "$add": [
                        { "$subtract": [
                          { "$subtract": [ "$when", new Date(0) ] },
                          { "$mod": [
                            { "$subtract": [ "$when", new Date(0) ] },
                            OneDay
                          ]}
                        ]},
                        new Date(0)
                      ]
                    },
                    "count": { "$sum": 1 }
                  }}
                ],
                function(err,results) {
                  if (err) callback(err);
                  async.each(results,function(result,callback) {
                    DataStore.update(
                      { "date": result._id },
                      { "$inc": { "count": result.count } },
                      { "upsert": true },
                      callback
                    );
                  },callback);
                }
              );
            }
          ],
          callback
        );
      }
    ],
    // Return result or error
    function(err) {
      if (err) throw err;
      DataStore.find({},{ "_id": 0 })
        .sort({ "date": 1 })
        .exec(function(err,results) {
        if (err) throw err;
        console.log(results);
        db.close();
      });
    }
  );

});

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

तो डेटाबेस को ऐसा करने की कोशिश न करें और मजबूर करें। निश्चित रूप से SQL प्रश्नों के उदाहरण हैं जो डेटाबेस सर्वर पर यह "विलय" करते हैं, लेकिन यह वास्तव में वहां एक अच्छा विचार नहीं था और वास्तव में एक समान "क्लाइंट" मर्ज प्रक्रिया के साथ संभाला जाना चाहिए क्योंकि यह केवल डेटाबेस ओवरहेड बना रहा है जो वास्तव में है ' टी की आवश्यकता है।

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




  1. Redis
  2.   
  3. MongoDB
  4.   
  5. Memcached
  6.   
  7. HBase
  8.   
  9. CouchDB
  1. एकल क्वेरी में मोंगोडब में 2 संग्रह से डेटा प्राप्त करें

  2. जाँच करें कि क्या दस्तावेज़ es7 async/प्रतीक्षा का उपयोग करके मोंगोडब में मौजूद है

  3. ऐसे दस्तावेज़ खोजें जिनके सरणी फ़ील्ड में किसी दिए गए सरणी के कम से कम n तत्व हों

  4. मोंगोइड/रेल 3 में एम्बेडेड ऑब्जेक्ट्स को क्वेरी करना (कम से कम, न्यूनतम ऑपरेटर और सॉर्टिंग)

  5. उपयोगकर्ता लॉगिन node.js और mongoose के साथ काम नहीं कर रहा है