Meteor Collection Transform: выполняется ли это на сервере или на клиенте? или это зависит
Я хочу использовать преобразование для создания "виртуального поля" из коллекции. Однако новое поле, которое я добавляю (внутри функции преобразования), добавляет довольно много данных в возвращаемый документ.
Это нормально, если преобразование происходит внутри клиента. Если это делается на стороне сервера, тогда будут проблемы с пропускной способностью.
Итак, мне интересно, выполняется ли преобразование на сервере или на клиенте, или это зависит от того, как я нахожу/извлекаю документ?
Ответы
Ответ 1
UPDATE: возможно сделать преобразование на сервере.
У вас может быть преобразование на клиенте следующим образом:
return YourCollection.find({}, {transform: function (doc) {
doc.test = true;
return true;
}});
Метеор игнорирует 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();
});
Ответ 2
Вы можете использовать преобразование с обеих сторон, когда вы указываете опцию преобразования в коллекцию или findOne, выборку и т.д.
transform Функция
Дополнительная функция преобразования. Документы будут переданы через эту функцию перед возвратом из fetch или findOne и перед передачей обратным вызовам наблюдения, разрешения и отказа.
Если вам нужно получить необработанный документ из коллекции с опцией преобразования.
myCollection.findOne({},{transform:null})
Ответ 3
Вы можете добавить и использовать следующую функцию:
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".
Ответ 4
Вы также можете добавить преобразование непосредственно в определение коллекции. Примечание. Как уже упоминалось выше, при обновлении возникает риск хранения дополнительных данных в вашей коллекции. Для коллекций только для чтения это не проблема.
Я также ожидаю, что это будет жить в общей папке 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;
})();
Ответ 5
Существует также пакет meteor, который позволяет добавлять преобразования на стороне сервера для публикации https://atmospherejs.com/maximum/server-transform