使用每个文档中的其他字段构建响应式发布

时间:2015-06-12 15:56:29

标签: mongodb meteor meteor-publications

我想制作包含其他几个字段的出版物,但我不想使用Collection.aggregate并在收集更改时丢失我的出版物更新(因此我无法使用{其中{1}}。)

我计划使用self.added来实现这一目标。我有两个主要的限制因素:

  1. 我不想发布所有文档字段
  2. 我想使用一些未发布的字段来创建新的字段。例如,我有一个字段Cursor.observeChanges,我存储了一个item _id数组。我不想发布它,但我希望发布一个{field}字段长度的item字段
  3. 方法来了:

    1. 我计划查找查询。我从来没有这样做,所以我想知道是否可能。一般(简化)查询结构如下:http://jsfiddle.net/Billybobbonnet/1cgrqouj/(我无法在此处正确显示代码)

    2. 基于the count example in Meteor documentation,我将查询存储在变量item_count中,以便在客户取消订阅时停止更改通知:

    3. handle
      1. 我在查询前添加了一个标记self.onStop(function () { handle.stop(); }); ,并在调用initializing = true;之前将其设置为true。只有在初始化发布时,我才使用此标志来更改self.ready();变量。所以基本上,我改变了我的itemCount
      2. switch

        我想在我的代码中进行大的更改之前检查这种方法是否良好且可行。如果这是正确的方法,有人可以确认我吗?

2 个答案:

答案 0 :(得分:3)

即使将字段作为数据库查询的一部分,也可以相对轻松地将字段保密。 self.added的最后一个参数是传递给客户端的对象,因此您可以删除/修改/删除要发送给客户端的字段。

这是你的小提琴的修改版本。这应该做你要求的。 (老实说,我不确定为什么你的小提琴中的observeChanges功能之后有什么链接,所以也许我误解了你,但是看看你的其余问题应该是这样的。抱歉,如果我弄错了。)

var self = this;

// Modify the document we are sending to the client.
function filter(doc) {
  var length = doc.item.length;

  // White list the fields you want to publish.
  var docToPublish = _.pick(doc, [
      'someOtherField'
  ]);

  // Add your custom fields.
  docToPublish.itemLength = length;

  return docToPublish;                        
}

var handle = myCollection.find({}, {fields: {item:1, someOtherField:1}})
            // Use observe since it gives us the the old and new document when something is changing. 
            // If this becomes a performance issue then consider using observeChanges, 
            // but its usually a lot simpler to use observe in cases like this.
            .observe({
                added: function(doc) {
                    self.added("myCollection", doc._id, filter(doc));
                },
                changed: function(newDocument, oldDocument)
                    // When the item count is changing, send update to client.
                    if (newDocument.item.length !== oldDocument.item.length)
                        self.changed("myCollection", newDocument._id, filter(newDocument));
                },
                removed: function(doc) {
                    self.removed("myCollection", doc._id);                    
                });

self.ready();

self.onStop(function () {
  handle.stop();
});

答案 1 :(得分:1)

要解决您的第一个问题,您需要告诉MongoDB它应该在游标中返回哪些字段。省去你不想要的字段:

MyCollection.find({}, {fields: {'a_field':1}});

解决你的第二个问题也很简单,我建议使用collection helpers packages。您可以轻松完成此任务,如下所示:

// Add calculated fields to MyCollection.
MyCollection.helpers({
  item_count: function() {
    return this.items.length;
  }
});

这将在将对象添加到游标之前运行,并将在动态计算的返回对象上创建属性,而不是存储在MongoDB中。