在 Meteor.js 中使用多个 Mongodb 数据库

IT技术 javascript node.js mongodb meteor smartcollection
2021-02-01 13:29:54

2Meteor.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
3个回答

更新

现在可以连接到远程/多个数据库:

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

<mongo_url>mongodb url在哪里,例如mongodb://127.0.0.1:27017/meteor(带有数据库名称)

目前有一个缺点:没有 Oplog

旧答案

目前这是不可能的。每个流星应用程序都绑定到一个数据库。

有几种方法可以解决这个问题,但它的value可能更复杂:

一种选择 - 使用单独的 Meteor 应用程序

在您的其他流星应用程序中(例如在同一台机器上的 6000 端口运行)。您仍然可以具有react性,但您需要通过方法调用代理插入、删除和更新

服务器:

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 连接

这使用 node js mongodb 本机驱动程序。

这是连接到数据库,就像您在任何其他节点 js 应用程序中所做的一样。

没有可用的react,你不能使用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();
   });
});
@JoePrivett 服务器上的任何地方。
2021-03-13 13:29:54
@Emily 太棒了,我已经等了很长时间了。在客户端上我们使用相同的普通集合是吗?
2021-03-18 13:29:54
如果数据库具有不同的集合名称,则此方法有效,但如果您在两个数据库中具有相同的集合名称,则此方法无效。有谁知道这是怎么做到的吗?
2021-03-20 13:29:54
实际上可能有一个由不同数据库服务器支持的集合;请参阅下面的我的答案。
2021-04-09 13:29:54
你把这两行代码放在哪里?在 if (Meteor.isServer) {} 块中,在 Meteor.startup(function () {}); 堵塞 ?
2021-04-12 13:29:54

这实际上是可能的,使用内部接口:

var d = new MongoInternals.RemoteCollectionDriver("<mongo url>");
C = new Mongo.Collection("<collection name>", { _driver: d });
快速提示,如果你发现你的集合是空的:确保在 mongodb url 的末尾包含 db 名称,它会默默地失败,你的集合只会显示为空。如果你想连接到你在 4444 端口上运行的另一个本地流星 mongodb 实例,而 mongo 在 4445 上,则 url 将如下所示:mongodb://127.0.0.1:4445/meteor
2021-04-04 13:29:54
请注意,这应该只在服务器上运行,即在“if (Meteor.isServer) {”块内。您还必须添加 "C = new Mongo.Collection("<collection name>");" 到您的“if (Meteor.isClient) {”块。
2021-04-09 13:29:54
你把这两行代码放在哪里?在“if (Meteor.isServer){}”块中,在“Meteor.startup(function(){});” 堵塞 ?我不断收到“ReferenceError: C is not defined”。
2021-04-11 13:29:54

答案是肯定的:可以设置多个 Meteor.Collections 来从不同的 mongdb 数据库服务器检索数据。

作为@Akshat 的回答,您可以初始化自己的MongoInternals.RemoteCollectionDriver实例,通过该实例Mongo.Collection可以创建 s。

但这里还有一些要谈的。与@Akshat 的回答相反,我发现在这种情况下仍然可以使用 Oplog 支持。

初始化 custom 时MongoInternals.RemoteCollectionDriver不要忘记指定 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 支持相当简单。如果你想知道这两行代码下面发生了什么,你可以继续阅读这篇文章的其余部分。

在 的构造函数中RemoteCollectionDriverMongoConnection将创建一个底层代码

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

棘手的部分是:如果MongoConnection使用oplogUrl提供的创建OplogHandle则将初始化,并开始拖尾 Oplog(源代码):

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

正如这篇博客所描述的:在Meteor.publish内部调用Cursor.observeChanges创建一个ObserveHandle实例,它会自动跟踪数据库中发生的任何未来更改。

目前有两种观察者驱动程序:PollingObserveDriver采用轮询和差异策略的传统驱动程序,以及OplogObseveDriver有效地使用 Oplog-tailing 来监视数据更改的 。要决定应用哪一个,请observeChanges执行以下过程(源代码):

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实现这一点,需要满足几个要求。最简单的一个是:底层MongoConnection实例应该有一个有效的OplogHandle. 这就是我们需要oplogUrl在创建时指定的确切原因MongoConnection

这需要标记为正确答案!我已经标记了这篇文章,希望管理员或 OP 可以切换答案!
2021-03-28 13:29:54