web-dev-qa-db-ja.com

Mongooseと単一のnode.jsプロジェクトの複数のデータベース

サブプロジェクトを含むNode.jsプロジェクトを実行しています。 1つのサブプロジェクトには1つのMongodbデータベースがあり、Mongooseはdbのラップとクエリに使用されます。しかし、問題は

  • Mongooseでは、1つの接続でモデルが構築されるため、単一のmongooseインスタンスで複数のデータベースを使用することはできません。
  • 複数のmongooseインスタンスを使用するために、Node.jsはrequire()にキャッシングシステムがあるため、複数のモジュールインスタンスを許可しません。 Node.jsでモジュールキャッシュを無効にすることは知っていますが、mongooseにのみ必要なため、良いソリューションではないと思います。

    私はcreateConnection()openSet()をマングースで使用しようとしましたが、解決策ではありませんでした。

    私はサブプロジェクトに新しいmongooseインスタンスを渡すために、mongooseインスタンスをディープコピーしようとしました( http://blog.imaginea.com/deep-copy-in-javascript/RangeError: Maximum call stack size exceeded

とにかく、複数のデータベースをmongooseで使用したり、この問題の回避策を使用したりすることを知りたいですか?マングースはとても簡単で速いと思うからです。または推奨事項として他のモジュール?

103
pupot

できることの1つは、各プロジェクトにサブフォルダーがあることです。そのため、そのサブフォルダにmongooseをインストールし、各サブアプリケーションの独自のフォルダからmongooseをrequire()します。プロジェクトルートまたはグローバルからではありません。したがって、1つのサブプロジェクト、1つのmongooseインストール、および1つの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を使用して複数のデータベースにアクセスできます。

34
yemaw

ファインマニュアル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' }
}));

スキーマを共有できることは確かですが、確認する必要があります。

186
robertklep

別の方法として、Mongooseはデフォルトインスタンスの新しいインスタンスのコンストラクターをエクスポートします。そのため、このようなことが可能です。

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

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

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

これは、個別のデータソースを使用する場合や、ユーザーまたはリクエストごとに個別のデータベースコンテキストを使用する場合に非常に便利です。これを行う際に大量の接続を作成する可能性があるため、注意する必要があります。インスタンスが不要な場合は必ずdisconnect()を呼び出し、各インスタンスで作成されるプールサイズを制限してください。

30
Eric

かなり遅いですが、これは誰かを助けるかもしれません。現在の回答では、接続とモデルに同じファイルを使用していると仮定しています。

実際には、モデルを異なるファイルに分割する可能性が高くなります。メインファイルで次のようなものを使用できます。

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はデータベース名です。

22
Tahnik Mustasin