web-dev-qa-db-ja.com

Meteor.jsで複数のMongodbデータベースを使用する

2 Meteor.Collectionsが2つの異なるmongdbデータベースサーバーからデータを取得することは可能ですか?

Dogs = Meteor.Collection('dogs')        // mongodb://192.168.1.123:27017/dogs
Cats = Meteor.Collection('cats')        // mongodb://192.168.1.124:27017/cats
37
Athena Wisdom

更新

リモート/複数のデータベースに接続できるようになりました:

var database = new MongoInternals.RemoteCollectionDriver("<mongo url>");
MyCollection = new Mongo.Collection("collection_name", { _driver: database });

<mongo_url>は、mongodb://127.0.0.1:27017/meteor(データベース名付き)などのmongodb URLです

現時点でこれには1つの欠点があります:Oplogなし

古い答え

現時点ではこれは不可能です。各流星アプリは1つのデータベースにバインドされています。

これを回避する方法はいくつかありますが、その価値よりも複雑になる可能性があります。

1つのオプション-別のMeteorアプリを使用する

他の流星アプリ(同じマシンのポート6000で実行されている例)。あなたはまだ反応性を持つことができますが、メソッド呼び出しを介して挿入、削除、更新をプロキシする必要があります

サーバ:

Cats = Meteor.Collection('cats')

Meteor.publish("cats", function() {
    return Cats.find();
});

Meteor.methods('updateCat, function(id, changes) {
    Cats.update({_id: id}, {$set:changes});
});

現在のMeteorアプリ:

var connection = DDP.connect("http://localhost:6000");

connection.subscribe("cats");
Cats = Meteor.Collection('cats', {connection: connection});

//To update a collection
Cats.call("updateCat", <cat_id>, <changes);

別のオプション-カスタムmongodb接続

これは、ノードjs mongodbネイティブドライバーを使用します。

これは、他のノードjsアプリで行うようにデータベースに接続します。

no反応性が利用可能であり、new Meteor.Collectionタイプのコレクションは使用できません。

var mongodb = Npm.require("mongodb"); //or var mongodb = Meteor.require("mongodb") //if you use npm package on atmosphere

var db = mongodb.Db;
var mongoclient = mongodb.MongoClient;
var Server = mongodb.Server;

var db_connection = new Db('cats', new Server("127.0.0.1", 27017, {auto_reconnect: false, poolSize: 4}), {w:0, native_parser: false});

db.open(function(err, db) {
    //Connected to db 'cats'

    db.authenticate('<db username>', '<db password>', function(err, result) {
      //Can do queries here
      db.close();
   });
});
57
Akshat

これは、内部インターフェイスを使用して実際に可能です。

var d = new MongoInternals.RemoteCollectionDriver("<mongo url>");
C = new Mongo.Collection("<collection name>", { _driver: d });
26
Emily

答えは[〜#〜] yes [〜#〜]:複数のMeteor.Collectionsを設定して、異なるmongdbデータベースからデータを取得することが可能です。サーバー。

@Akshatからの回答として、独自のMongoInternals.RemoteCollectionDriverインスタンスを初期化できます。これにより、Mongo.Collectionsを作成できます。

しかし、ここでさらに説明することがあります。 @Akshatの答えに反して、そのような状況でもOplogのサポートは引き続き利用できることがわかりました。

カスタムMongoInternals.RemoteCollectionDriverを初期化するとき、DO NOTはOplog URLの指定を忘れます:

var driver = new MongoInternals.RemoteCollectionDriver(
    "mongodb://localhost:27017/db", 
    {
      oplogUrl: "mongodb://localhost:27017/local"
    });
var collection = new Mongo.Collection("Coll", {_driver: driver});

フードの下

上記のように、Oplogサポートを有効にするのはかなり簡単です。これらの2行のコードの下で何が起こったかを知りたい場合は、投稿の残りを読み続けることができます。

RemoteCollectionDriverのコンストラクターで、基礎となるMongoConnectionが作成されます。

MongoInternals.RemoteCollectionDriver = function (
  mongo_url, options) {
  var self = this;
  self.mongo = new MongoConnection(mongo_url, options);
}; 

トリッキーな部分は:MongoConnectionoplogUrlを指定して作成された場合、OplogHandleが初期化され、Oplogの末尾を開始します( source code ):

if (options.oplogUrl && ! Package['disable-oplog']) {  
  self._oplogHandle = new OplogHandle(options.oplogUrl, self.db.databaseName);
  self._docFetcher = new DocFetcher(self);
}

blog で説明したように、Meteor.publishは内部でCursor.observeChangesを呼び出してObserveHandleインスタンスを作成します。

現在、2種類のオブザーバードライバーがあります。poll-and-diff戦略を取る従来のPollingObserveDriverと、Oplog-tailingを効果的に使用してデータ変更を監視するOplogObseveDriverです。どれを適用するかを決定するために、observeChangesは次の手順を取ります( source code ):

var driverClass = canUseOplog ? OplogObserveDriver : PollingObserveDriver;
observeDriver = new driverClass({
  cursorDescription: cursorDescription,
  mongoHandle: self,
  multiplexer: multiplexer,
  ordered: ordered,
  matcher: matcher,  // ignored by polling
  sorter: sorter,  // ignored by polling
  _testOnlyPollCallback: callbacks._testOnlyPollCallback
});

canUseOplogをtrueにするには、いくつかの要件を満たす必要があります。最小限の1つは、基になるMongoConnectionインスタンスに有効なOplogHandleが必要です。これが、oplogUrlの作成中にMongoConnectionを指定する必要がある正確な理由です。

24
Zephyre