Meteor:不同用户的唯一 MongoDB URL

问题描述:

我非常热衷于使用 Meteor 作为我下一个项目的框架.但是,对于来自不同客户的用户,需要将客户数据分离到不同的 MongoDB 实例中.

I'm very keen to utilize Meteor as the framework for my next project. However, there is a requirement to keep customer data separated into different MongoDB instances for users from different customers.

我在这个线程上读到它可以像使用这个一样简单:

I have read on this thread that it could be as simple as using this:

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

但是,我在 server/server.js 上遇到了这个错误.我正在使用流星 0.9.2.2使用meteor-platform 1.1.0.

However, I was dished this error on my server/server.js. I'm using meteor 0.9.2.2 with meteor-platform 1.1.0.

Exception from sub Ep9DL57K7F2H2hTBz Error: A method named '/documents/insert' is already defined
    at packages/ddp/livedata_server.js:1439
    at Function._.each._.forEach (packages/underscore/underscore.js:113)
    at _.extend.methods (packages/ddp/livedata_server.js:1437)
    at Mongo.Collection._defineMutationMethods (packages/mongo/collection.js:888)
    at new Mongo.Collection (packages/mongo/collection.js:208)
    at Function.Documents.getCollectionByMongoUrl (app/server/models/documents.js:9:30)
    at null._handler (app/server/server.js:12:20)
    at maybeAuditArgumentChecks (packages/ddp/livedata_server.js:1594)
    at _.extend._runHandler (packages/ddp/livedata_server.js:943)
    at packages/ddp/livedata_server.js:737

有没有好心人能指点一下我是不是哪里弄错了?

Can anyone be so kind as to enlighten me whether or not I have made a mistake somewhere?

谢谢.

溴,伊森

这是我的 server.js

This is my server.js

Meteor.publish('userDocuments', function () {   
    // Get company data store's mongo URL here. Simulate by matching domain of user's email.
    var user = Meteor.users.findOne({ _id: this.userId });
    if (!user || !user.emails) return;

    var email = user.emails[0].address;
    var mongoUrl = (email.indexOf('@gmail.com') >= 0) ? 
        'mongodb://localhost:3001/company-a-db' :
        'mongodb://localhost:3001/company-b-db';

    // Return documents
    return Documents.getCollectionByMongoUrl(mongoUrl).find();
});

这是服务器端model.js

and this is the server side model.js

文档=函数(){};

var documentCollections = { };

var documentCollections = { };

Documents.getCollectionByMongoUrl = function (url) {
    if (!(url in documentCollections)) {
        var driver = new MongoInternals.RemoteCollectionDriver(url);
        documentCollections[url] = new Meteor.Collection("documents", { _driver: driver });
    }

    return documentCollections[url];
};

观察:第一次尝试新建一个 Meteor.Collection 工作正常.我可以继续多次使用该集合.但是,当我注销并以另一家公司的其他用户身份登录时(在本例中使用不是来自 @gmail.com 的电子邮件),则会引发上述错误.

Observation: The first attempt to new a Meteor.Collection works fine. I can continue to use that collection multiple times. But when I log out and login as another user from another company (in this example by using an email that is not from @gmail.com), the error above is thrown.

我相信 Meteor 通过你作为第一个参数传递给它们的名称在内部区分它的集合,所以当你第二次创建文档"集合时,它试图覆盖结构.因此,第二次尝试创建 /documents/insert 方法时出现错误.

I believe Meteor distinguish its collections internally by the name you pass to them as the first argument, so when you create the "documents" collection the second time, it tries to override the structure. Hence the error when trying to create the /documents/insert method the second time.

要解决此问题,您可以为集合名称应用后缀.所以,而不是:

To work around this, you could apply a suffix to your collection name. So instead of:

new Meteor.Collection('documents', { _driver: driver });

你应该尝试:

new Meteor.Collection('documents_' + userId, { _driver: driver })