Как опубликовать представление / преобразование коллекции в Meteor?

Я сделал compilation

var Words = new Meteor.Collection("words"); 

и опубликовал его:

 Meteor.publish("words", function() { return Words.find(); }); 

так что я могу получить к нему доступ на клиенте. Проблема в том, что эта коллекция будет очень большой, и я просто хочу опубликовать ее преобразование. Например, предположим, что я хочу опубликовать сводку под названием «num words by length», которая представляет собой массив из int, где index – это длина слова, а item – количество слов этой длины. Так

 wordsByLength[5] = 12; 

означает, что имеется 12 слов длины 5. В терминах SQL это простой GROUP BY / COUNT над исходным набором данных. Я пытаюсь создать шаблон на клиенте, который скажет что-то вроде

  • У вас есть N слов длины X

для каждой длины. Мой вопрос сводится к «У меня есть данные в форме A, и я хочу опубликовать преобразованную версию B».

UPDATE Вы можете преобразовать коллекцию на сервере следующим образом:

 Words = 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 = Words.find().observe({ added: function (document) { self.added('collection_name', document._id, transform(document)); }, changed: function (newDocument, oldDocument) { self.changed('collection_name', oldDocument._id, transform(newDocument)); }, removed: function (oldDocument) { self.removed('collection_name', oldDocument._id); } }); self.onStop(function () { observer.stop(); }); self.ready(); }); 

Чтобы обернуть преобразования, упомянутые в других ответах, вы можете использовать пакет, который я разработал, meteor-middleware . Для этого он обеспечивает хороший API-интерфейс для подключения. Поэтому вместо простого преобразования вы можете складывать их один на другой. Это позволяет повторное использование кода, проверку прав доступа (например, удаление или объединение полей на основе разрешений) и т. Д. Таким образом, вы можете создать class, который позволяет собирать документы так, как вы хотите.

Но для вашего конкретного случая вы, возможно, захотите изучить конвейер агрегации MongoDB . Если действительно есть много слов, вы, вероятно, не хотите передавать их все с сервера MongoDB на сервер Meteor. С другой стороны, в конвейере агрегации отсутствует реактивность, которую вы, возможно, захотите. Так что опубликованные документы меняются, когда слова приходят и уходят.

Чтобы решить, что вы можете использовать другой пакет, который я разработал, PeerDB . Это позволяет вам указывать триггеры, которые будут называться реакционно называемыми изменениями данных и храниться в базе данных. Затем вы можете просто использовать обычную публикацию для отправки счета клиенту. Недостатком является то, что все пользователи должны быть заинтересованы в одной коллекции. Он работает глобально, а не для пользователя. Но если вас интересует количество слов в целом коллекции, вы можете сделать что-то вроде (в CoffeesScript):

 class WordCounts extends Document @Meta name: 'WordCounts' class Words extends Document @Meta name: 'Words' triggers: => countWords: @Trigger ['word'], (newDocument, oldDocument) -> # Document has been removed. if not newDocument._id WordCounts.update length: oldDocument.word.length , $inc: count: -1 # Document has been added. else if not oldDocument._id WordCounts.update length: newDocument.word.length , $inc: count: 1 # Word length has changed. else if newDocument.word.length isnt oldDocument.word.length WordCounts.update length: oldDocument.word.length , $inc: count: -1 WordCounts.update length: newDocument.word.length , $inc: count: 1 

И тогда вы можете просто публиковать документы WordCounts :

 Meteor.publish 'counts', -> WordCounts.documents.find() 

Вы можете собрать подсчеты, пройдя каждый документ в Словах ( курсор для каждого )

 var countingCursor = Words.find({}); var wordCounts = {}; countingCursor.forEach(function (word) { wordCounts[word.length].count += 1; wordCounts[word.length].words = wordCounts[word.length].words || [] wordCounts[word.length].words.push(word); }); 

создать локальную коллекцию,

 var counts = new Meteor.Collection('local-counts-collection', {connection: null}); 

и вставьте свои ответы

 var key, value; for (key in wordCounts) { value = object[key]; counts.insert({ length: key, count: value.count, members: value.words }); } 

Графы теперь представляют собой коллекцию, которая просто не хранится в Монго.

Не испытано!

  • Как отформатировать дату в шаблоне meteor
  • Каковы наилучшие методы структурирования большого приложения Meteor со многими файлами шаблонов HTML?
  • Как заставить Meteor.Call вернуть значение для шаблона?
  • Насколько эффективным может Метеор быть вместе с огромной коллекцией среди многих клиентов?
  • Заказ файлов css и js, загруженных Meteor
  • Как я могу полностью удалить, а затем переустановить Meteor.js?
  • Публикуйте определенную информацию для Meteor.users и дополнительную информацию для Meteor.user
  • Публикация / подписка на несколько подмножеств одной и той же серверной коллекции
  • Невозможно создать рабочий проект meteor.js на бродячем боксе
  • Как преобразовать данные, полученные через Meteor.publish?
  • Сообщение для входа в Facebook: «URL Blocked: эта переадресация не удалась, потому что URI перенаправления не включен в настройки клиента OAuth».
  • Давайте будем гением компьютера.