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

नोडज से मोंगोडब या नेवला के लिए गतिशील डेटाबेस कनेक्शन

यह दूसरों की मदद करने के लिए है जो खुद को उसी तरह की स्थिति में पा सकते हैं जैसे मैंने किया था। मुझे आशा है कि इसे मानकीकृत किया जा सकता है। मुझे नहीं लगता कि हर बार जब किसी को बहु-किरायेदार आवेदन करने की आवश्यकता होती है तो हमें पहिया को फिर से शुरू करना चाहिए।

यह उदाहरण एक बहु-किरायेदार संरचना का वर्णन करता है जिसमें प्रत्येक क्लाइंट का अपना डेटाबेस होता है। जैसा कि मैंने कहा कि ऐसा करने का एक बेहतर तरीका हो सकता है, लेकिन क्योंकि मुझे स्वयं सहायता नहीं मिली, यह मेरा समाधान था।

तो ये वे लक्ष्य हैं जिन्हें यह समाधान लक्षित करता है:

  • प्रत्येक ग्राहक की पहचान उपडोमेन द्वारा की जाती है जैसे client1.application.com,
  • एप्लिकेशन जांचता है कि उप डोमेन मान्य है या नहीं,
  • एप्लिकेशन देखता है और मास्टर डेटाबेस से कनेक्शन जानकारी (डेटाबेस यूआरएल, क्रेडेंशियल, आदि) प्राप्त करता है,
  • एप्लिकेशन क्लाइंट डेटाबेस से जुड़ता है (काफी हद तक क्लाइंट को सौंप दिया जाता है),
  • एप्लिकेशन अखंडता और संसाधन प्रबंधन सुनिश्चित करने के लिए उपाय करता है (उदाहरण के लिए एक ही क्लाइंट के सदस्यों के लिए एक ही डेटाबेस कनेक्शन का उपयोग करें, बजाय नया कनेक्शन बनाने के)।

यहां कोड है

आपके app.js . में फ़ाइल

app.use(clientListener()); // checks and identify valid clients
app.use(setclientdb());// sets db for valid clients

मैंने दो मिडलवेयर बनाए हैं:

  • clientListener - कनेक्ट करने वाले क्लाइंट की पहचान करने के लिए,
  • setclientdb - क्लाइंट की पहचान के बाद मास्टर डेटाबेस से क्लाइंट विवरण प्राप्त करता है, और फिर क्लाइंट डेटाबेस से कनेक्शन स्थापित करता है।

क्लाइंट लिस्टनर मिडलवेयर

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

var Clients = require('../models/clients');
var basedomain = dbConfig.baseDomain;
var allowedSubs = {'admin':true, 'www':true };
allowedSubs[basedomain] = true;
function clientlistener() {
return function(req, res, next) {
    //console.dir('look at my sub domain  ' + req.subdomains[0]);
    // console.log(req.session.Client.name);

    if( req.subdomains[0] in allowedSubs ||  typeof req.subdomains[0] === 'undefined' || req.session.Client && req.session.Client.name === req.subdomains[0] ){
        //console.dir('look at the sub domain  ' + req.subdomains[0]);
        //console.dir('testing Session ' + req.session.Client);
        console.log('did not search database for '+ req.subdomains[0]);
        //console.log(JSON.stringify(req.session.Client, null, 4));
        next();
    }
    else{

        Clients.findOne({subdomain: req.subdomains[0]}, function (err, client) {
            if(!err){
                if(!client){
                    //res.send(client);
                    res.send(403, 'Sorry! you cant see that.');
                }
                else{
                    console.log('searched database for '+ req.subdomains[0]);
                    //console.log(JSON.stringify(client, null, 4));
                    //console.log(client);
                   // req.session.tester = "moyo cow";
                    req.session.Client = client;
                    return next();

                }
            }
            else{
                console.log(err);
                return next(err)
            }

        });
    }

   }
 }

module.exports = clientlistener;

सेटक्लाइंटडीबी मिडलवेयर:

मैं यह सुनिश्चित करने के लिए फिर से सब कुछ जांचता हूं कि ग्राहक वैध है। फिर सत्र से प्राप्त जानकारी के साथ क्लाइंट के डेटाबेस से कनेक्शन खोला जाता है।

मैं सभी सक्रिय कनेक्शनों को एक वैश्विक वस्तु में संग्रहीत करना भी सुनिश्चित करता हूं, ताकि प्रत्येक अनुरोध पर डेटाबेस से नए कनेक्शन को रोका जा सके (हम कनेक्शन के साथ प्रत्येक क्लाइंट mongodb सर्वर को अधिभारित नहीं करना चाहते हैं)।

var mongoose = require('mongoose');
//var dynamicConnection = require('../models/dynamicMongoose');
function setclientdb() {
    return function(req, res, next){
        //check if client has an existing db connection                                                               /*** Check if client db is connected and pooled *****/
    if(/*typeof global.App.clientdbconn === 'undefined' && */ typeof(req.session.Client) !== 'undefined' && global.App.clients[req.session.Client.name] !== req.subdomains[0])
    {
        //check if client session, matches current client if it matches, establish new connection for client
        if(req.session.Client && req.session.Client.name === req.subdomains[0] )
        {
            console.log('setting db for client ' + req.subdomains[0]+ ' and '+ req.session.Client.dbUrl);
            client = mongoose.createConnection(req.session.Client.dbUrl /*, dbconfigoptions*/);


            client.on('connected', function () {
                console.log('Mongoose default connection open to  ' + req.session.Client.name);
            });
            // When the connection is disconnected
            client.on('disconnected', function () {
                console.log('Mongoose '+ req.session.Client.name +' connection disconnected');
            });

            // If the Node process ends, close the Mongoose connection
            process.on('SIGINT', function() {
                client.close(function () {
                    console.log(req.session.Client.name +' connection disconnected through app termination');
                    process.exit(0);
                });
            });

            //If pool has not been created, create it and Add new connection to the pool and set it as active connection

            if(typeof(global.App.clients) === 'undefined' || typeof(global.App.clients[req.session.Client.name]) === 'undefined' && typeof(global.App.clientdbconn[req.session.Client.name]) === 'undefined')
            {
                clientname = req.session.Client.name;
                global.App.clients[clientname] = req.session.Client.name;// Store name of client in the global clients array
                activedb = global.App.clientdbconn[clientname] = client; //Store connection in the global connection array
                console.log('I am now in the list of active clients  ' + global.App.clients[clientname]);
            }
            global.App.activdb = activedb;
            console.log('client connection established, and saved ' + req.session.Client.name);
            next();
        }
        //if current client, does not match session client, then do not establish connection
        else
        {
            delete req.session.Client;
            client = false;
            next();
        }
    }
    else
    {
        if(typeof(req.session.Client) === 'undefined')
        {
           next();
        }
        //if client already has a connection make it active
        else{
            global.App.activdb = global.App.clientdbconn[req.session.Client.name];
            console.log('did not make new connection for ' + req.session.Client.name);
            return next();
        }

    }
    }
}

module.exports = setclientdb;

आखिरी लेकिन कम से कम नहीं

चूंकि मैं नेवले और देशी नेवले के संयोजन का उपयोग कर रहा हूं, इसलिए हमें अपने मॉडलों को रन टाइम पर संकलित करना होगा। कृपया नीचे देखें

इसे अपने app.js . में जोड़ें

// require your models directory
var models = require('./models');

// Create models using mongoose connection for use in controllers
app.use(function db(req, res, next) {
    req.db = {
        User: global.App.activdb.model('User', models.agency_user, 'users')
        //Post: global.App.activdb.model('Post', models.Post, 'posts')
    };
    return next();
});

व्याख्या:

जैसा कि मैंने पहले कहा था कि मैंने सक्रिय डेटाबेस कनेक्शन ऑब्जेक्ट को स्टोर करने के लिए एक वैश्विक ऑब्जेक्ट बनाया है:global.App.activdb

फिर मैं इस कनेक्शन ऑब्जेक्ट का उपयोग नेवला मॉडल बनाने (संकलित) करने के लिए करता हूं, जब मैं इसे req ऑब्जेक्ट की db प्रॉपर्टी में संग्रहीत करता हूं:req.db . मैं ऐसा इसलिए करता हूं ताकि उदाहरण के लिए मैं अपने नियंत्रक में अपने मॉडलों तक पहुंच सकूं।

मेरे उपयोगकर्ता नियंत्रक का उदाहरण:

exports.list = function (req, res) {
    req.db.User.find(function (err, users) {

        res.send("respond with a resource" + users + 'and connections  ' + JSON.stringify(global.App.clients, null, 4));
        console.log('Worker ' + cluster.worker.id + ' running!');
    });

};

मैं वापस आऊंगा और अंत में इसे साफ कर दूंगा। अगर कोई मेरी मदद करना चाहता है, तो अच्छा होगा।



  1. Redis
  2.   
  3. MongoDB
  4.   
  5. Memcached
  6.   
  7. HBase
  8.   
  9. CouchDB
  1. मैक पर मोंगोडब डेटाबेस का स्थान

  2. नेवला सत्यापन त्रुटियों को संभालना - कहाँ और कैसे?

  3. केवल मानों की एक सरणी के रूप में परिणाम लौटाएं

  4. मूल HTML दृश्य प्रस्तुत करें?

  5. मोंगो:ऐसे आइटम ढूंढें जिनमें एक निश्चित फ़ील्ड नहीं है