Meteor:发布另一个出版物的子集

时间:2015-06-03 21:15:45

标签: meteor meteor-publications

我的服务器上有自定义发布(以某种方式加入2个集合)。

本出版物的结果正是我所需要的,但对于表演问题,我希望避免将其完全发送给客户。

  

如果我不关心表演,我只会订阅   出版并做类似的事情   theCollection.find({"my":"filter"})

因此,我试图找到一种方法来发布自定义发布的子集,以便将过滤器应用于服务器端的自定义发布。

有没有办法链接或过滤出版物(服务器端)?

对于这个问题,我们可以假设自定义出版物看起来像这样,不能修改:

Meteor.publish('customPublication', function() {
    var sub = this;

    var aCursor = Resources.find({type: 'someFilter'});
    Mongo.Collection._publishCursor(aCursor, sub, 'customPublication');

    sub.ready();
  });

2 个答案:

答案 0 :(得分:1)

如果我理解正确的问题,那么您正在寻找https://atmospherejs.com/reywood/publish-composite

让你“使用反应连接从各种集合中发布一组相关文档。这样可以轻松地一次发布整个文档树。已发布的集合是被动的,并且在添加/更改/删除时会更新造“。

答案 1 :(得分:0)

好的,我来到以下解决方法。我只是添加了一个根据其他集合更新的新集合,而不是在出版物上工作。为此,我使用meteor hooks package

function transformDocument(doc)
{
doc.aField = "aValue"; // do what you want here
return doc;
}

ACollection.after.insert(function(userId, doc)
{
    var transformedDocument = transformDocument(doc);
    AnotherCollection.insert(transformedDocument);
});

ACollection.after.update(function(userId, doc, fieldNames, modifier, options)
{
    var transformedDocument = transformDocument(doc);
    delete transformedDocument._id;
    AnotherCollection.update(doc._id,{$set:transformedDocument});
});

ACollection.after.remove(function(userId, doc)
{
    AnotherCollection.remove(doc._id);
});

然后我有了新的集合,我可以按常规方式发布子集

优点:

  • 您可以在此数据库中过滤所需的任何内容,无需担心该字段是虚拟还是真实
  • 每次db更改时只能执行一次操作。这避免了多个出版物合并相同的数据

Cave eats:

  • 这需要一个Collection = more space
  • 2 db可能并不总是同步,原因很简单:
    • 客户端手动更改了" AnotherCollection"
    • 的数据
    • 你有" ACollection"在你添加" AnotherCollection"。
    • 之前
    • 转换函数或源集合架构在某些时候发生了变化

解决此问题:

AnotherCollection.allow({
    insert: function () {
        return Meteor.isServer;
    },
    update: function () {
        return Meteor.isServer;
    },
    remove: function () {
        return Meteor.isServer;
    }
});

并在流星启动时同步(即从头开始构建集合)。只进行一次维护或添加此新系列后。

Meteor.startup(function()
{
    AnotherCollection.remove({});
    var documents = ACollection.find({}).fetch();
    _.each(documents, function(doc)
    {
    var transformedDocument = transformDocument(doc);
    AnotherCollection.insert(transformedDocument);
    });
});