【问题标题】:Meteor: Publish a subset of another publicationMeteor:发布另一个出版物的子集
【发布时间】:2015-08-18 07:13:03
【问题描述】:

我的服务器上有一个自定义出版物(以某种方式加入了 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();
  });

【问题讨论】:

    标签: meteor meteor-publications


    【解决方案1】:

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

    它让您“使用响应式联接从各种集合发布一组相关文档。这使得一次发布整个文档树变得容易。发布的集合是响应式的,并且会在添加/更改/删除时更新制作。”

    【讨论】:

    • 我的出版物很好,但我需要创建已发布集的子集。
    【解决方案2】:

    好的,我找到了以下解决方法。我没有处理出版物,而是简单地添加了一个我根据其他集合更新的新集合。为此,我使用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);
    });
    

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

    好处:

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

    洞穴吃:

    • 这需要多一个 Collection = 更多空间
    • 2 db 可能并不总是同步,这有几个原因:
      • 客户端手动更改了“AnotherCollection”的数据
      • 在添加“AnotherCollection”之前,“ACollection”中有文档。
      • 转换函数或源集合架构在某些时候发生了变化

    解决这个问题:

    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);
        });
    });
    

    【讨论】:

      猜你喜欢
      • 2018-03-27
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2015-03-12
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多