단일 node.js 프로젝트의 몽구스 및 다중 데이터베이스


123

하위 프로젝트가 포함 된 Node.js 프로젝트를 수행하고 있습니다. 하나의 하위 프로젝트에는 하나의 Mongodb 데이터베이스가 있고 Mongoose는 db를 래핑하고 쿼리하는 데 사용됩니다. 하지만 문제는

  • Mongoose는 모델이 하나의 연결에서 빌드되기 때문에 단일 mongoose 인스턴스에서 여러 데이터베이스를 사용할 수 없습니다.
  • 여러 몽구스 인스턴스를 사용하기 위해 Node.js는 .js 파일에 캐싱 시스템이 있으므로 여러 모듈 인스턴스를 허용하지 않습니다 require(). Node.js에서 모듈 캐싱을 비활성화하는 것을 알고 있지만 몽구스에만 필요하므로 좋은 솔루션이 아니라고 생각합니다.

    내가 사용 해봤 createConnection()openSet()몽구스에 있지만 해결책이 아니었다.

    새 몽구스 인스턴스를 하위 프로젝트에 전달하기 위해 mongoose 인스턴스 ( http://blog.imaginea.com/deep-copy-in-javascript/ ) 를 딥 복사하려고 시도했지만 RangeError: Maximum call stack size exceeded.

몽구스와 함께 여러 데이터베이스를 사용 하거나이 문제에 대한 해결 방법이 있는지 알고 싶습니다. 몽구스는 아주 쉽고 빠르다고 생각하기 때문입니다. 아니면 권장 사항으로 다른 모듈이 있습니까?

답변:


38

한 가지 할 수있는 일은 각 프로젝트에 대한 하위 폴더가있을 수 있다는 것입니다. 따라서 해당 하위 폴더에 mongoose를 설치하고 각 하위 응용 프로그램의 자체 폴더에서 mongoose를 필요로합니다. 프로젝트 루트 또는 글로벌이 아닙니다. 따라서 하나의 하위 프로젝트, 하나의 몽구스 설치 및 하나의 몽구스 인스턴스.

-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

이제 mongoose로 여러 데이터베이스에 액세스 할 수 있습니다.


2
이는 모든 프로젝트가 자체적으로 연결된다는 것을 의미합니다. 100,000 개의 연결을 관리 할 수 ​​없습니다. useDb같은 커넥션 풀을 사용하는 명령어를 사용하는 편이 낫다고 생각합니다 .
xpepermint 2015

1
xpepermint는 useDb에 대한 예제를 보여줄 수 있습니까?
현재이

4
이것은 프로젝트에 큰 부담으로 보입니다. 그렇게 생각하지 않습니까?
Eshwar Prasad Yaddanapudi

1
응용 프로그램 당 몇 가지 다른 연결 인스턴스 (예 : 사용자 DB, 세션 DB 및 응용 프로그램 데이터)를 갖는 것은 절대적으로 좋습니다. '큰 부담'이 아니거나 확장 문제를 유발하지 않으며 일반적인 사용 사례입니다.
Iain Collins

당신은 내 가장 친한 친구입니다! 정말 고마워! 그것은 나를 위해 작동합니다! 감사!
Biruel Rick

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
예, 명명 된 연결과 공유 스키마가 제 생각에 갈 길입니다. 각 연결에는 Robert의 예에 따라 고유 한 모델이 필요합니다.
사이먼 홈즈

21
또한 useDb()기본 연결 풀을 공유하기 위해 3.8에서 체크 아웃 할 수 있습니다. github.com/LearnBoost/mongoose/wiki/…
aaronheckmann 2013

1
자동 생성 된 데이터베이스가 있다고 가정합니다 (데이터베이스의 n 개라고 말함). 한두 개가 아닙니다. 각 데이터베이스에 대해 별도의 모델을 생성하지 않고 이들에 연결할 수있는 방법이 있습니까?
Anooj Krishnan G

1
@AnoojKrishnanG 나는 그것이 가능하다고 생각하지 않습니다. 각 데이터베이스에 대해 별도로 모델을 생성해야합니다. 그러나 내 답변에서 이미 언급했듯이 연결간에 스키마 를 공유 할 수 있으므로 코딩 시간을 절약 할 수 있습니다.
robertklep

1
여러 모델, 즉 DB간에 스키마를 공유 할 수 있습니다. 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 = require ( 'mongoose'); const 스키마 = mongoose.Schema; const mySchema = 새 스키마 ({}); const mydbvar = mongoose.connection.useDb ( 'mydb') module.exports = mydbvar.model ( 'myCollection', MySchema);
Johnathan Enslin

2
확실히 가장 좋고 가장 실제적인 예입니다. SQL Server와 같은 것을 사용하는 경우와 마찬가지로 기본 db에 연결 한 다음 useDb를 활용하여 적절한 데이터베이스에서 DML을 대상으로 지정합니다. (사용자를 한 db에 보관하고 데이터를 다른 db에 보관하는 데 매우 유용합니다.) 궁극적으로 동일한 서버에 요청을 보낼 때 여러 연결을 시작할 필요가 없습니다. 이제 두 개의 다른 서버에 연결하는 경우 다른 물고기 주전자입니다.
Newclique

2
@Wade가 말했듯이, 내가 이해하는 한이 솔루션은 모든 데이터베이스가 동일한 서버에있을 때만 작동합니다. 이것이 OP의 질문에 대답하는지 확실하지 않으며 IMO는 약간 오해의 소지가 있습니다.
joniba

이것은 MongoDB Atlas에서에서 마이그레이션하고 test여러 연결을 피하는 데 필요한 것입니다 . 그러나 이전 db를 몽구스로 관리 할 필요가 없기 .db때문에 마지막에 ( const v1 = mongoose.connection.useDb('test').db)도 있습니다.
Polv

37

대안으로 Mongoose는 기본 인스턴스에서 새 인스턴스에 대한 생성자를 내 보냅니다. 그래서 이와 같은 것이 가능합니다.

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

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

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

이는 별도의 데이터 소스로 작업 할 때 그리고 각 사용자 또는 요청에 대해 별도의 데이터베이스 컨텍스트를 갖고 싶을 때 매우 유용합니다. 이 작업을 수행 할 때 많은 연결을 생성 할 수 있으므로주의해야합니다. 인스턴스가 필요하지 않은 경우 disconnect ()를 호출하고 각 인스턴스에서 생성되는 풀 크기를 제한해야합니다.


1
이것이 'Above Answer' 를 쓰는 또 다른 방법 입니까?
pravin

11
이것은 위의 답변이 아니라 더 좋습니다. 위의 답변은 불필요하게 Mongoose의 여러 복사본을 설치합니다.
Martín Valdés de León

이 방법을 사용하여 어떻게 쿼리를 작성합니까?
shahidfoy

2
await instance1.connection.collection('foo').insert({ foo: 'bar', }) await instance2.connection.collection('foo').insert({ foo: 'zoo', })
Abdallah Al Barmawi

실제로 모델과 데이터베이스는 물론 각 연결에 대해 완전히 다른 자격 증명을 가지고 있기 때문에 제 경우에는 더 잘 작동합니다.
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;
    };
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.