流星收集'客户'是集合的父母' Projects' 项目中的外键是' client_id'。
现在我希望使用客户端名称扩展Projects集合。如果没有客户父母,请创建客户名称' XXX'。 (很容易看到'孤儿'项目:只需将XXX作为客户名称)
流星代码如下:
collections.js
Client = new Mongo.Collection('clients');
Project = new Mongo.Collection('projects', {
transform: function (doc) {
var client = Client.findOne({"_id":doc.client_id},{"_id":0, "name":1});
if (!client) {
// Client name is 'XXX'
return _.extend(doc, {"client_name":"XXX"});
} else {
return _.extend(doc, {"client_name":client.name});
}
}
}
);
publications.js
Meteor.publish('clientNewYork', function () {
// This publication only New York clients, and only the name.
return Client.find({"city":"New York"}, {fields: {"name": 1}}, {sort: name: -1});
});
Meteor.publish('projects', function () {
return Project.find();
});
subscriptions.js
Meteor.subscribe('clientNewYork');
Meteor.subscribe('projects');
应用程序从第一个订阅开始:纽约所有客户的列表。 下一个屏幕是所有项目,富含客户名称。 重要:所有项目,不仅是来自纽约客户的项目。
发生了奇怪的事情:
不在纽约的客户的所有项目都会获得' XXX'作为客户名称。 这意味着该集合的转换会考虑该出版物。
我的怀疑:
非纽约客户在我的浏览器中不在MiniMongo中。 但我希望collection.js进入服务器上运行的数据库,而不是浏览器上的minimongo。
解决方法:
将客户端发布更改为所有客户端,而不仅仅是纽约客户端。 但我的感觉说这不好。
我在这里做错了吗?
答案 0 :(得分:0)
只要获取文件,就会对文档运行转换。你的怀疑是正确的:
当在客户端上获取项目文档时,它们每个都会查找相应的客户端文档。由于客户端上的find
将达到最小值,因此只会发布已发布的客户端(在您的情况下为NYC客户端)。
如果不了解您的实施细节,很难提出准确的解决方案。一些选项包括:
通过在项目中存储client_name
字段来规范化数据(避免转换)。缺点是每当您更新客户端的名称时,您还需要更新相应的项目。看看collection-hooks。
为客户提供更灵活的发布功能。如果您可以识别当前项目或当前项目集,则可以在订阅时将id或id数组传递给publish函数。通过这种方式,您仍然可以加入这两个集合,而无需发布整套客户文档。