Meteor:针对不同用户的唯一MongoDB URL

时间:2014-09-18 10:37:07

标签: mongodb meteor

我非常希望利用Meteor作为我下一个项目的框架。但是,需要将客户数据分离到不同客户的用户的不同MongoDB实例中。

我在this thread上读到它可能就像使用它一样简单:

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

但是,我在服务器/ server.js上抛出了这个错误。我正在使用meteor 0.9.2.2 与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

任何人都可以如此友善地告诉我,不管我是否在某处犯了错误?

感谢。

BR, 乙

编辑:这是我的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

Documents = function(){};

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),则会抛出上述错误。

2 个答案:

答案 0 :(得分:1)

下载了meteor的源代码,并偷看了mongo包。根据Hubert的建议,有一种方法 hack 必须在mongodb服务器上声明不同的集合名称。

在服务器端model.js中,我做了这些改编:

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

    return documentCollections[userId];
};

这里的超级黑客工作。使用时要小心!!!!

答案 1 :(得分:0)

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

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

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

你应该尝试:

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