187 votes

Mongoose et plusieurs bases de données dans un seul projet node.js

Je suis en train de réaliser un projet Node.js qui contient des sous-projets. Un sous-projet aura une base de données Mongodb et Mongoose sera utilisé pour envelopper et interroger la base de données. Mais le problème est

  • Mongoose ne permet pas d'utiliser plusieurs bases de données dans une seule instance de mongoose car les modèles sont construits sur une seule connexion.
  • Pour utiliser plusieurs instances de mongoose, Node.js ne permet pas de multiples instances de modules car il a un système de mise en cache dans require(). Je sais désactiver la mise en cache des modules dans Node.js mais je pense que ce n'est pas la bonne solution car cela n'est nécessaire que pour mongoose.

    J'ai essayé d'utiliser createConnection() et openSet() dans mongoose, mais ce n'était pas la solution.

    J'ai essayé de copier profondément l'instance de mongoose (http://blog.imaginea.com/deep-copy-in-javascript/) pour passer de nouvelles instances de mongoose au sous-projet, mais cela lance une erreur RangeError: Maximum call stack size exceeded.

Je veux savoir s'il existe des moyens d'utiliser plusieurs bases de données avec mongoose ou toute solution de contournement pour ce problème? Parce que je trouve que mongoose est assez facile et rapide. Ou d'autres modules à recommander?

2voto

PKInd007 Points 368

Une solution un peu optimisée (pour moi du moins). Écrivez ceci dans un fichier db.js et exigez-le partout où nécessaire, puis appelez-le avec un appel de fonction et vous êtes prêt à partir.

   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;
    };

1voto

NguyenTungs Points 115

J'utilise cette méthode et elle fonctionne très bien pour moi jusqu'à présent.

const mongoose = require('mongoose');

function makeNewConnection(uri) {
    const db = mongoose.createConnection(uri, {
        useNewUrlParser: true,
        useUnifiedTopology: true
    });

    db.on('error', function (error) {
        console.log(`MongoDB :: connection ${this.name} ${JSON.stringify(error)}`);
        db.close().catch(() => console.log(`MongoDB :: failed to close connection ${this.name}`));
    });

    db.on('connected', function () {
        mongoose.set('debug', function (col, method, query, doc) {
            console.log(`MongoDB :: ${this.conn.name} ${col}.${method}(${JSON.stringify(query)},${JSON.stringify(doc)})`);
        });
        console.log(`MongoDB :: connected ${this.name}`);
    });

    db.on('disconnected', function () {
        console.log(`MongoDB :: disconnected ${this.name}`);
    });

    return db;
}

// Use

const db1 = makeNewConnection(MONGO_URI_DB1);
const db2 = makeNewConnection(MONGO_URI_DB2);

module.exports = {
   db1,
   db2
}

0voto

Carl A Points 11

Je ne sais pas si cela aidera quelqu'un, mais c'est ce que j'ai fini par faire après avoir essayé de gérer plusieurs connexions avec Mongoose, et en fin de compte, me retrouver ici (depuis de nombreux endroits).

L'objet retourné par const mongoose = require("mongoose"); (re. Mongoose v.8) a une propriété 'connections', un tableau de connexions. Cela contient à son tour une propriété id, l'id du tableau, qui est retourné lorsque la connexion est établie.

J'ai donc fait quelque chose comme cela :

// db001URL est l'URL de connexion MongoDB, avec une base de données facultative
const db001conn = await mongoose.createConnection(db001URL).asPromise();
console.log("connecté à db001conn");
// définir une variable id quelque part : ici j'ai utilisé une fermeture
mongoID({ db001: db001conn.id });

// db002URL est une autre chaîne de connexion MongoDB
const db002conn = await mongoose.createConnection(db002URL).asPromise();
console.log("connecté à db002");
// définir une variable id quelque part : ici j'ai utilisé une fermeture
mongoID({ db002: db002conn.id });

Stocker l'id m'a permis de rappeler une des multiples connexions en utilisant mongoose.connections[id], ce qui signifiait également que je pouvais laisser l'objet Mongoose mutable et continuer ma vie sans m'en soucier.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X