0

我想制作一个包含几个附加字段的出版物,但我不想Collection.aggregate在集合更改时使用和丢失我的出版物更新(所以我也不能只self.added在其中使用)。

我计划使用Cursor.observeChanges以实现这一目标。我有两个主要限制:

  1. 我不想发布所有文档字段
  2. 我想使用一些未发布的字段来创建新字段。例如,我有一个存储_iditem数组的字段。item我不想发布它,但我想发布一个item_count字段长度为我的字段数组

方法来了:

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

  2. 根据Meteor 文档中的计数示例,我将查询存储在一个变量handle中,以便在客户端取消订阅时停止更改通知:

self.onStop(function () {
  handle.stop();
});
  1. initializing = true;我在查询之前添加了一个标志,并将其设置为true就在调用self.ready();. itemCount仅当发布已初始化时,我才使用此标志更改我的变量。所以基本上,我改变了我的switch样子:
switch (field) {
  case "item"
    if (!initializing)
      itemCount = raw_document.item.length;
      break;
  default:
}

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

4

2 回答 2

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();
});
于 2015-06-12T22:27:24.140 回答
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 中。

于 2015-06-12T20:08:41.290 回答