Как получить доступ к агрегированным данным коллекции в метеорном клиенте?

Я собрал некоторые данные и опубликовал их, но не знаю, как/где получить доступ к подписанным данным. Смогу ли я получить доступ к коллекции клиентов WeeklyOrders (которая определяется как коллекция только для клиентов, т.е. WeeklyOrders = new Mongo.Collection(null);)?

Кроме того, я вижу «я = это»; используется в нескольких примерах в Интернете, и я только что использовал его здесь, но не уверен, почему. Ценю любого, кто это объясняет.

Вот метод публикации:

Meteor.publish('customerOrdersByWeek', function(customerId) {
  check(customerId, String);
  var self = this;
  var pipeline = [
    { $match: {customer_id: customerId} },
    { $group: {
        _id : { week: { $week: "$_created_at" }, year: { $year: "$_created_at" } },
        weekly_order_value: { $sum: "$order_value" }
      }
    },
    { $project: { week: "$_id.week", year: "$_id:year" } },
    { $limit: 2 }
  ];
  var result = Orders.aggregate(pipeline);
  result.forEach(function(wo) {
    self.added('WeeklyOrders', objectToHash(wo._id), {year: wo.year, week: wo.week, order_value: wo.weekly_order_value});
  });
  self.ready();
});

Вот маршрут:

Router.route('/customers/:_id', {
  name: 'customerOrdersByWeek',
  waitOn: function() {
    return [
      Meteor.subscribe('customerOrdersByWeek', this.params._id)
    ];
  },
  data: function() { return Customers.findOne(this.params._id); }
});

Вот мой помощник по шаблону:

Template.customerOrdersByWeek.helpers({
  ordersByWeek: function() {
    return WeeklyOrders.find({});
  }
});

person Srini K    schedule 29.03.2016    source источник


Ответы (1)


Вам нужен var self = this (обратите внимание на переменную!), чтобы вызов self.added работал. Дополнительные сведения см. в этом вопросе. В качестве альтернативы вы можете использовать новые функции стрелок es6 (снова см. связанный вопрос).

Может быть более одной проблемы, но при вызове added вы указываете случайный идентификатор. Это представляет две проблемы:

  1. Если вы подпишетесь N раз, вы получите N одного и того же документа, отправленного клиенту (каждый с другим идентификатором). Дополнительные сведения см. в этом вопросе.
  2. Вы не можете сопоставить документ по идентификатору на клиенте.

На клиенте вы выполняете Customers.findOne(this.params._id), где this.params._id, как я полагаю, является идентификатором клиента... но ваши WeeklyOrders имеют случайные идентификаторы. Попробуйте это:

self.added('WeeklyOrders', customerId, {...});

обновленный ответ

Вам нужно будет добавить клиент -only collection в качестве своего рода почтового ящика, на который ваш издатель может отправлять WeeklyOrders:

client/collections/weekly-orders.js

WeeklyOrders = new Meteor.Collection('WeeklyOrders');

Кроме того, поскольку у вас может быть несколько документов для одного и того же пользователя, вам, вероятно, потребуется:

  1. Забудьте о том, что я сказал ранее, и просто используйте случайный идентификатор, но никогда не подписывайтесь больше одного раза. Это простое решение, но несколько хрупкое.

  2. Используйте составной индекс (объедините идентификатор клиента + неделя или что-то еще, что необходимо, чтобы сделать их уникальными).

Использование (2) и добавление поля customerId, чтобы вы могли найти документы на клиенте, приводит к чему-то вроде этого:

result.forEach(function (wo) {
  var id = customerId + wo.year + wo.week;
  self.added('WeeklyOrders', id, {
    customerId: customerId,
    year: wo.year,
    week: wo.week,
    order_value: wo.weekly_order_value,
  });
});

Теперь на клиенте можно найти все WeeklyOrders по customerId через WeeklyOrders.find({customerId: someCustomerId}).

Также обратите внимание, что вместо использования pub/sub вы также можете просто сделать все это в вызове метода. Оба нереактивны. pub/sub дает вам семантику коллекции (возможность вызывать find и т. д.), но добавляет дополнительную сложность, связанную с необходимостью иметь дело с идентификаторами.

person David Weldon    schedule 30.03.2016
comment
Я не думаю, что смогу использовать customerId вместо randomId, потому что все документы принадлежат одному и тому же клиенту. Они просто объединены по неделям. Я обновил вопрос, чтобы отразить ваши комментарии, но мне все еще нужна помощь в решении вопроса. Как я могу получить доступ к WeeklyOrders в клиенте? - person Srini K; 30.03.2016
comment
Я добавил дополнительную информацию к ответу. Надеюсь, это приблизит вас к решению. - person David Weldon; 31.03.2016
comment
Чего мне не хватало, так это коллекции на стороне клиента с тем же именем, что и в self.added, то есть WeeklyOrders = new Mongo.Collection("WeeklyOrders");. Без этого я не мог бы ссылаться на публикуемые данные. Пожалуйста, обновите свой ответ, чтобы я мог его принять. - person Srini K; 31.03.2016
comment
Ах, я пропустил, что ты этого не сделал. Упс. Ну, я обновил ответ. Лучше поздно, чем никогда, я полагаю. - person David Weldon; 31.03.2016