2016-02-04 30 views
2

我使用流星,并且自3天以来难以解决此问题。我搜索了stackoverflow,但答案似乎并不能满足我的需求。我有一个销售表,其中有以下数据。获取不同的对象与所有子文件mongo流星

{ 
"_id" : 1, 
"table" : "Table no 2", 
"name" : "Hot Coffee", 
"quantity" : 2, 
"price" : "$10", 
"seller" : "User", 
"createdAt" : ISODate("2016-01-06T12:57:17.152Z") 
}, 
{ 
"_id" : 2, 
"table" : "Table no 3A", 
"name" : "Hot Coffee", 
"quantity" : 1, 
"price" : "$10", 
"seller" : "User", 
"createdAt" : ISODate("2016-02-01T12:58:17.152Z") 
}, 
{ 
"_id" : 3, 
"table" : "Table no 3A", 
"name" : "Pizza", 
"quantity" : 2, 
"price" : "$50", 
"seller" : "User", 
"createdAt" : ISODate("2016-01-06T12:58:17.152Z") 
}, 
{ 
"_id" : 4, 
"table" : "2A", 
"name" : "Pizza", 
"quantity" : 5, 
"price" : "$50", 
"seller" : "User", 
"createdAt" : ISODate("2016-02-02T11:55:17.152Z") 
}, 

我期待不同的表名与所有的添加量,

{ 
"name":"Hot Coffee", 
"quantity": 3 
}, 
{ 
"name":"Pizza", 
"quantity": 7 
} 

我尝试了不同的功能,但它似乎只显示一个结果。

回答

1

使用aggregation framework这一点,但由于总量不大流星尚不支持,你需要得到安装聚合框架包 - 它不会做什么特别的,只是包装了一些对你的蒙戈方法。

只是流星添加meteorhacks:aggregate你应该做生意。这将为流星添加适当的聚合支持。

现在您将需要此管道来实现所需的结果。在蒙戈外壳,运行以下命令:

var pipeline = [ 
    { 
     "$group": { 
      "_id": "$name", 
      "quantity": { "$sum": "$quantity" } 
     } 
    }, 
    { 
     "$project": { 
      "name": "$_id", "_id": 0, "quantity": 1 
     } 
    } 
]; 

db.sales.aggregate(pipeline); 

样本输出

{ 
    "result" : [ 
     { 
      "quantity" : 7, 
      "name" : "Pizza" 
     }, 
     { 
      "quantity" : 3, 
      "name" : "Hot Coffee" 
     } 
    ], 
    "ok" : 1 
} 

什么这种聚合操作确实是它采用了$group管道步骤组由name字段中的所有文件,并且每个不同的组通过累加器运算符$sum获得每个组的数字字段数量的累计总量。下一个管道$project将把之前管道流文档的字段重新整形为所需的结构。

流星,你可以发布这些结果给Sales收集使用以下方式的客户端,只要你有加总包到您的流星应用:

Meteor.publish('getDistinctSalesWithTotalQuantity', function (opts) { 

    var initializing = 1; 

    function run(action) { 

     // Define the aggregation pipeline (aggregate(pipeline)) 
     var pipeline = [ 
      { 
       "$group": { 
        "_id": "$name", 
        "quantity": { "$sum": "$quantity" } 
       } 
      }, 
      { 
       "$project": { 
        "name": "$_id", "_id": 0, "quantity": 1 
       } 
      } 
     ]; 

     Sales.aggregate(pipeline).forEach(function(e){ 
      this[action]('distinct-sales', e.name, e) 
      this.ready() 
     }); 
    }; 

    // Run the aggregation initially to add some data to your aggregation collection 
    run('added'); 

    // Track any changes on the collection we are going to use for aggregation 
    var handle = Sales.find({}).observeChanges({ 
     added(id) { 
      // observeChanges only returns after the initial `added` callbacks 
      // have run. Until then, we don't want to send a lot of 
      // `self.changed()` messages - hence tracking the 
      // `initializing` state. 
      if (initializing && initializing--) run('changed'); 
     }, 
     removed(id) { 
      run('changed'); 
     }, 
     changed(id) { 
      run('changed'); 
     }, 
     error(err) { 
      throw new Meteor.Error('Aaaaaaaaah! Grats! You broke it!', err.message) 
     } 
    }); 

    // Stop observing the cursor when client unsubs. 
    // Stopping a subscription automatically takes 
    // care of sending the client any removed messages. 
    this.onStop(function() { 
     handle.stop(); 
    }); 
}); 

上述观察变化,如果必要的重新运行聚合。