13

我想使用转换从集合中创建一个“虚拟字段”。但是,我添加的新字段(在转换函数中)正在向返回的文档添加相当多的数据。

如果转换发生在客户端内部,这很好。如果它是在服务器端完成的,那么就会有带宽问题。

所以我想知道转换是在服务器上还是在客户端上完成的,还是取决于我如何查找/获取文档?

4

5 回答 5

26

更新:可以在服务器上进行转换。

您可以像这样在客户端上进行转换:

return YourCollection.find({}, {transform: function (doc) {
   doc.test = true;
   return true;
}});

Meteor 忽略transform已发布的查询(从内部Meteor.publish)。客户端将文档视为转换不存在。

如果您想在服务器上使用转换,您可以这样做:

YourCollection = new Mongo.Collection("collection_name"); 

Meteor.publish("yourRecordSet", function() {

  //Transform function
  var transform = function(doc) {
    doc.date = new Date();
    return doc;
  }

  var self = this;

  var observer = YourCollection.find().observe({
      added: function (document) {
      self.added('collection_name', document._id, transform(document));
    },
    changed: function (newDocument, oldDocument) {
      self.changed('collection_name', newDocument._id, transform(newDocument));
    },
    removed: function (oldDocument) {
      self.removed('collection_name', oldDocument._id);
    }
  });

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

  self.ready();

});
于 2013-08-07T07:28:00.203 回答
2

您可以添加和使用以下功能:

Meteor.publishWithTransform = function(publicationName, cursorGetter , transform)
{
    transform = transform || function(o){return o;};
    Meteor.publish(publicationName, function ()
    {
        var cursor = cursorGetter.apply(this, arguments);
        var collectionName = cursor._cursorDescription.collectionName;

        var self = this;

        var observer = cursor.observe({
            added: function (document) {
                self.added(collectionName, document._id, transform(document));
            },
            changed: function (newDocument, oldDocument) {
                self.changed(collectionName, newDocument._id, transform(newDocument));
            },
            removed: function (oldDocument) {
                self.removed(collectionName, oldDocument._id);
            }
        });

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

        self.ready();
    });
}

用法(服务器端):

Meteor.publishWithTransform("publication-name", function () {
    aCollection.find({})
}, function (item)
{
    item.aField = "something";
    return item;
});

缺点:如果您保存已发布的文档,您也将保存添加的更改。在这里,客户不知道在发布期间添加了属性“aField”。

于 2015-06-02T10:20:07.053 回答
1

当您为集合或 findOne、fetch 等指定转换选项时,您可以在两侧使用转换

变换函数
可选的变换函数。在从 fetch 或 findOne 返回之前,以及在传递给观察、允许和拒绝的回调之前,将通过此函数传递文档。

如果您需要使用转换选项从集合中获取原始文档。

myCollection.findOne({},{transform:null})
于 2013-08-07T03:38:43.370 回答
1

您也可以直接在集合定义中添加转换。注意:如上所述,这可能会在更新时将额外数据存储到您的集合中。对于只读集合,这不是一个真正的问题。

我也希望它存在于共享的 lib 文件夹或类似文件夹中,客户端和服务器都可以看到这个定义。

var Assignment;

// Every record in this collection will now be an 
// instance of the Assignment class.
this.AssignmentsReport = new Mongo.Collection("assignments", {
  transform: function(doc) {
    return new Assignment(doc._id, doc.assignId, doc.masterId);
  }
});

// Creating a class instance to actually map the new object.
Assignment = (function() {
  function Assignment(_id, assignId, masterId) {
    var assign, ref;
    this._id = _id;
    this.assignId = assignId;
    this.masterId = masterId;
    this.assign = (ref = Assignments.find({
      _id: this.assignId
    }).fetch()) != null ? ref[0] : void 0;
  }

  return Assignment;

})();
于 2015-07-22T00:32:10.750 回答
1

还有一个流星包,允许在服务器端添加转换以发布https://atmospherejs.com/maximum/server-transform

于 2016-04-29T09:21:03.733 回答