एकल नोड.जेएस परियोजना में Mongoose और कई डेटाबेस


123

मैं एक Node.js परियोजना कर रहा हूं जिसमें उप परियोजनाएं शामिल हैं। एक उप परियोजना में एक Mongodb डेटाबेस होगा और Mongoose db को रैप करने और क्वेरी करने के लिए उपयोग किया जाएगा। लेकिन समस्या यह है

  • मानगो एकल डेटाबेस में कई डेटाबेस का उपयोग करने की अनुमति नहीं देता है क्योंकि मॉडल एक कनेक्शन पर निर्मित होते हैं।
  • कई आम उदाहरणों का उपयोग करने के लिए, Node.js कई मॉड्यूल उदाहरणों की अनुमति नहीं देता है क्योंकि इसमें कैशिंग प्रणाली है require()। मुझे पता है कि Node.js में मॉड्यूल कैशिंग अक्षम है, लेकिन मुझे लगता है कि यह अच्छा समाधान नहीं है क्योंकि यह केवल मोंगोज़ के लिए आवश्यक है।

    मैं उपयोग करने के लिए createConnection()और openSet()आम में कोशिश की है , लेकिन यह समाधान नहीं था।

    मैंने उप परियोजना में नए मानदंड उदाहरणों को पारित करने के लिए मोंगोज़ उदाहरण ( http://blog.imaginea.com/deep-copy-in-javascript/ ) को कॉपी करने की कोशिश की है , लेकिन यह फेंक रहा है RangeError: Maximum call stack size exceeded

मैं जानना चाहता हूं कि क्या इस समस्या के लिए मानगो या किसी वर्कअराउंड के साथ कई डेटाबेस का उपयोग करने का कोई रास्ता है? क्योंकि मुझे लगता है कि मानसून काफी आसान और तेज है। या सिफारिशों के रूप में किसी भी अन्य मॉड्यूल?

जवाबों:


38

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

-app_root/
--foo_app/
---db_access.js
---foo_db_connect.js
---node_modules/
----mongoose/
--bar_app/
---db_access.js
---bar_db_connect.js
---node_modules/
----mongoose/

Foo_db_connect.js में

var mongoose = require('mongoose');
mongoose.connect('mongodb://localhost/foo_db');
module.exports = exports = mongoose;

Bar_db_connect.js में

var mongoose = require('mongoose');
mongoose.connect('mongodb://localhost/bar_db');
module.exports = exports = mongoose;

Db_access.js फ़ाइलों में

var mongoose = require("./foo_db_connect.js"); // bar_db_connect.js for bar app

अब, आप कई डेटाबेस को मानस के साथ एक्सेस कर सकते हैं।


2
इसका मतलब है कि हर प्रोजेक्ट का अपना कनेक्शन होगा। आप 100k कनेक्शन का प्रबंधन नहीं कर पाएंगे। मुझे लगता है कि useDbकमांड का उपयोग करना बेहतर होगा जो समान कनेक्शन पूल का उपयोग करता है।
xpepermint

1
xpepermint क्या आप उपयोग के लिए एक उदाहरण दिखाने में सक्षम हैं - मैं इस मुद्दे पर वर्तमान में stackoverflow.com/questions/37583198/…
Lion789

4
यह परियोजना पर भारी बोझ की तरह दिखता है। क्या आपको ऐसा नहीं लगता?
ईश्वर प्रसाद यद्दनपुदी

1
कुछ अलग कनेक्शन इंस्टेंसेस (उदाहरण के लिए एक उपयोगकर्ता DB, एक सत्र DB, और अनुप्रयोग डेटा के लिए) होने के बाद प्रति आवेदन बिल्कुल ठीक है। यह 'बहुत बड़ा बोझ' नहीं है और न ही स्केलिंग की समस्या पैदा करने वाला है और यह एक सामान्य उपयोग का मामला है।
इयान कॉलिंस

आप सबसे अच्छे मेरे दोस्त हैं! बहुत बहुत धन्यवाद! इससे मेरा काम बनता है! धन्यवाद!
बिरुएल रिक

214

ठीक मैनुअल के अनुसार , कई डेटाबेस से कनेक्ट करने के लिए उपयोग किया createConnection() जा सकता है।

हालाँकि, आपको प्रत्येक कनेक्शन / डेटाबेस के लिए अलग मॉडल बनाने की आवश्यकता है:

var conn      = mongoose.createConnection('mongodb://localhost/testA');
var conn2     = mongoose.createConnection('mongodb://localhost/testB');

// stored in 'testA' database
var ModelA    = conn.model('Model', new mongoose.Schema({
  title : { type : String, default : 'model in testA database' }
}));

// stored in 'testB' database
var ModelB    = conn2.model('Model', new mongoose.Schema({
  title : { type : String, default : 'model in testB database' }
}));

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


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

21
useDb()अंतर्निहित कनेक्शन पूल साझा करने के लिए 3.8 में उपलब्ध चेकआउट : github.com/LearnBoost/mongoose/wiki/…
aaronheckmann

1
मान लीजिए कि मेरे पास स्वतः-जनरेट किया गया डेटाबेस है (डेटाबेस की संख्या n कहें)। एक या दो नहीं। क्या प्रत्येक डेटाबेस के लिए अलग मॉडल बनाए बिना इनसे जुड़ने का कोई तरीका है?
अनुज कृष्णन जी

1
@AnoojKrishnanG मुझे नहीं लगता कि यह संभव है, नहीं। आपको प्रत्येक डेटाबेस के खिलाफ अलग से मॉडल बनाने की आवश्यकता है। हालाँकि, जैसा कि मैंने पहले ही अपने उत्तर में कहा था, आप स्कीमा को कनेक्शन के बीच साझा करने में सक्षम हो सकते हैं , जिससे कुछ कोडिंग समय बच सकता है।
रॉबर्टबेलप

1
आप विभिन्न मॉडलों में स्कीमा साझा कर सकते हैं, और इसलिए डीबी। var newSchema = new mongoose.Schema({ ... }), var model2 = conn1.model('newModel', newSchema),var model2 = conn2.model('newModel', newSchema)
अनुदान

42

बहुत देर से लेकिन यह किसी की मदद कर सकता है। वर्तमान उत्तर मानता है कि आप अपने कनेक्शन और मॉडल के लिए एक ही फ़ाइल का उपयोग कर रहे हैं।

वास्तविक जीवन में, एक उच्च संभावना है कि आप अपने मॉडल को अलग-अलग फ़ाइलों में विभाजित कर रहे हैं। आप अपनी मुख्य फ़ाइल में कुछ इस तरह का उपयोग कर सकते हैं:

mongoose.connect('mongodb://localhost/default');

const db = mongoose.connection;

db.on('error', console.error.bind(console, 'connection error:'));
db.once('open', () => {
  console.log('connected');
});

जो डॉक्स में वर्णित है कि यह कैसा है। और फिर अपनी मॉडल फ़ाइलों में, निम्न जैसा कुछ करें:

import mongoose, { Schema } from 'mongoose';

const userInfoSchema = new Schema({
  createdAt: {
    type: Date,
    required: true,
    default: new Date(),
  },
  // ...other fields
});

const myDB = mongoose.connection.useDb('myDB');

const UserInfo = myDB.model('userInfo', userInfoSchema);

export default UserInfo;

जहाँ myDB आपके डेटाबेस का नाम है।


धन्यवाद - मैं एक ही आवेदन के भीतर 3 अलग-अलग डेटाबेस का उपयोग करने में सक्षम था: कॉन्स्टेंट मोंगोज़ = आवश्यकता ('मोंगोज़'); const स्कीमा = mongoose.Schema; const mySchema = new स्कीमा ({}); const mydbvar = mongoose.connection.useDb ('mydb') मॉड्यूल.exports = mydbvar.model ('myCollection', MySchema);
जॉनथन एनसलिन

2
निश्चित रूप से सबसे अच्छा और सबसे वास्तविक दुनिया उदाहरण। डिफ़ॉल्ट db से कनेक्ट करें (जैसे यदि आप SQL सर्वर जैसी किसी चीज का उपयोग कर रहे थे) और फिर उचित डेटाबेस पर अपने DML को लक्षित करने के लिए useDb का लाभ उठाएं। (आपके उपयोगकर्ताओं को एक db में और दूसरे में आपके डेटा को रखने के लिए बहुत उपयोगी है।) जब आप एक ही सर्वर को अनुरोध भेज रहे हैं तो कई कनेक्शन शुरू करने की आवश्यकता नहीं है। अब, यदि आप दो अलग-अलग सर्वरों से जुड़ रहे हैं, तो यह मछली का एक अलग केतली है।
न्यूक्लिक

2
जैसा कि @Wade ने कहा, जहां तक ​​मैं समझता हूं कि यह समाधान केवल तभी काम करता है जब सभी डेटाबेस एक ही सर्वर पर हों। यह स्पष्ट नहीं है कि यह ओपी के सवाल का जवाब देता है और आईएमओ थोड़ा भ्रामक है।
जोनिबा

यह सिर्फ मैं क्या MongoDB एटलस से प्रवास के लिए की जरूरत है test, और भी कई कनेक्शन होने से बचने के लिए। हालाँकि, मैं भी .dbअंत में ( const v1 = mongoose.connection.useDb('test').db) के रूप में पुराने डीबी को प्रबंधित करने की आवश्यकता नहीं है।
पोल्व

37

एक वैकल्पिक दृष्टिकोण के रूप में, Mongoose डिफॉल्ट उदाहरण पर एक नए उदाहरण के लिए एक कंस्ट्रक्टर को निर्यात करता है। तो ऐसा कुछ संभव है।

var Mongoose = require('mongoose').Mongoose;

var instance1 = new Mongoose();
instance1.connect('foo');

var instance2 = new Mongoose();
instance2.connect('bar');

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


1
क्या यह another उपरोक्त उत्तर ’ लिखने का एक और तरीका है ?
प्रवीण

11
यह उपरोक्त उत्तर नहीं है, यह बेहतर है। उपर्युक्त उत्तर अनावश्यक रूप से मानगो की कई प्रतियों को स्थापित करता है।
मार्टीन वाल्डेस डी लियोन

मैं इस पद्धति का उपयोग करके प्रश्न कैसे बनाऊंगा?
शाहिदोय

2
await instance1.connection.collection('foo').insert({ foo: 'bar', }) await instance2.connection.collection('foo').insert({ foo: 'zoo', })
अब्दुल्ला अल बरमावी

वास्तव में मेरे मामले में बेहतर काम कर रहा है क्योंकि मेरे पास प्रत्येक कनेक्शन के लिए पूरी तरह से अलग साख है, अकेले मॉडल और डेटाबेस दें।
tzn

0

थोड़ा अनुकूलित (मेरे लिए कम से कम) समाधान। इसे एक फ़ाइल db.js पर लिखें और जहाँ भी आवश्यकता हो, और इसे किसी फ़ंक्शन कॉल के साथ कॉल करें और आप जाने के लिए अच्छे हैं।

   const MongoClient = require('mongodb').MongoClient;
    async function getConnections(url,db){
        return new Promise((resolve,reject)=>{
            MongoClient.connect(url, { useUnifiedTopology: true },function(err, client) {
                if(err) { console.error(err) 
                    resolve(false);
                }
                else{
                    resolve(client.db(db));
                }
            })
        });
    }

    module.exports = async function(){
        let dbs      = [];
        dbs['db1']     = await getConnections('mongodb://localhost:27017/','db1');
        dbs['db2']     = await getConnections('mongodb://localhost:27017/','db2');
        return dbs;
    };
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.