如何访问meteor客户端中的聚合收集数据?

时间:2016-03-29 23:16:16

标签: javascript mongodb meteor iron-router meteor-helper

我汇总了一些数据并将其发布,但我不确定访问订阅数据的方式/位置。我是否能够访问WeeklyOrders客户端集合(定义为仅客户端集合,即WeeklyOrders = new Mongo.Collection(null);)?

另外,我看到" self = this;"在网上使用了几个例子,我在这里使用它,但不知道为什么。感谢任何人解释这一点。

这是发布方法:

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({});
  }
});

1 个答案:

答案 0 :(得分:3)

你想要var self = this(注意var!),以便调用self.added。有关详细信息,请参阅this question。或者,您可以使用新的es6箭头功能(再次查看链接的问题)。

可能存在多个问题,但在您致电added时,您提供的是随机ID。这提出了两个问题:

  1. 如果您订阅了N次,您将获得发送给客户端的相同文档的N(每个具有不同的ID)。有关详细信息,请参阅this question
  2. 您无法在客户端上按ID匹配文档。
  3. 在客户端上,您正在执行Customers.findOne(this.params._id),我认为this.params._id是客户ID ...但您的WeeklyOrders有随机ID。试一试:

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

    更新回答

    您需要添加client-only collection作为一种邮箱,供发布商将WeeklyOrders发送到:

    <强>的客户机/集合/每周-orders.js

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

    另外,因为您可以为同一个用户提供多个文档,所以您可能需要:

    1. 忘记我之前说过的内容并使用随机ID,但永远不要订阅一次。这是一个简单的解决方案,但有些脆弱。

    2. 使用复合索引(合并客户ID +周,或任何必要的内容以使其唯一)。

    3. 使用(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等的能力),但它增加了必须处理id的额外复杂性。