2014-04-22 32 views
0

我需要聚合 蒙戈骨料与多个聚合类型

- Country: One, Car: Volvo, Name: Smith, Price: 100 
- Country: One, Car: BMW, Name: Smith, Price: 200 
- Country: Two, Car: Romeo, Name: Joe, Price: 50 
- Country: Two, Car: KIA, Name: Joe, Price: 110 
- Country: Two, Car: KIA, Name: Joe, Price: 90 

(名称是唯一的,每一个都拥有单一国家汽车)

的结果,我希望(不需要多元化以下数据

):

- Name: Smith, Type: Volvos, Country: One, Val: 1 // Count of car-type 
- Name: Smith, Type: BMWs, Country: One, Val: 1 
- Name: Smith, Type: Total, Country: One, Val: 2 // Count of all his cars 
- Name: Smith, Type: Price, Country: One, Val: 300 // Total car price 
- Name: Joe, Type: Romeos, Country: Two, Val: 1 
- Name: Joe, Type: KIAs, Country: Two, Val: 2 
- Name: Joe, Type: Total, Country: Two, Val: 3 
- Name: Joe, Type: Price, Country: Two, Val: 250 

例如这是一个pivotized数据版本中生成报告

Country | Name | Volvos | BMWs | Romeos | KIAs | Total | Price 
---------------------------------------------------------------- 
One  | Smith |  1 | 1 |  |  |  2 | 300 
---------------------------------------------------------------- 
Two  | Joe |  |  |  1 | 2 |  3 | 250 
     | Other |  ? | ? |  ... etc 

我想如果蒙戈聚合框架可以解决这个问题,或者我应该去与铁杆的map-reduce?

+0

试试这个使用聚合。 bcoz如果数据变大,那么很难去核心地图减少 – Mayuri

+0

@Mayuri地图缩减和聚合是两个完全不同的pruposes不同的事情,MR不应该内联运行到您自己的应用程序,例如 – Sammaye

+0

主要问题是我不确定这是否适用于AF。 –

回答

0

聚合应该对此很好。 最简单的2个独立的命令...... 如果您收藏被称为汽车,你可以像这样运行的东西:

db.cars.aggregate([{$group:{_id:{"Country":"$Country","Name":"$Name"},"sum":{$sum:1},"price":{$sum:"$Price"}}}]) 


db.cars.aggregate([{$group:{_id:{"Country":"$Country","Name":"$Name","Car":"$Car"},"sum":{$sum:1},"price":{$sum:"$Price"}}}]) 
+0

你的命令的结果并不是我所期望的:每个人没有*所有车的数量*,并且没有*每个人的总车价*。 –

+0

@RustemMustafin更新(从_id删除汽车) –

+0

现在我们错过了每个人给定类型​​的汽车数量(请参阅Joe有2个KIA和3辆汽车)。 –

1

可能有一些技巧,但这样做,用的类型,我不相信一个可变数目你可以在一个聚合查询中得到这一切,但是,你可以将整个表格分成两部分。

我应该提到的是,总数可以计算出客户端应该是相当快的。

我还应该注意到,聚合框架目前无法“合并”两个输出:http://docs.mongodb.org/manual/reference/operator/aggregation/out/,但您可以对两个结果进行排序,使其排序相同。

首先,你希望你的总(如果你是通过聚合框架这样做):

db.cars.aggregate({ 
    {$group: { 
     _id: { 
      Country: '$country', 
      Name: '$Name' 
     }, 
     car_count: {$sum: 1}, 
     value_total: {$sum: '$Val'} 
    }}, 
    {$sort: {_id: 1}} // we now sort by the country and name 
}) 

所以,现在你希望你的每车总数:

db.cars.aggregate({ 
    {$group: { 
     _id: { 
      Country: '$country', 
      Name: '$Name', 
      Type: '$Type' 
     }, 
     sort_key: { // We add this so we can sort the same as the totals 
      Country: '$Country', 
      Name: '$Name' 
     }, 
     car_count: {$sum: 1}, 
     value_total: {$sum: '$Val'} 
    }}, 
    {$sort: {sort_key: 1}} // we now sort by the country and name 
}) 

现在你可以在例如,JavaScript会迭代第一组结果,即总数,在嵌套循环中迭代来自其他聚合的详细结果,将其全部打印出来。

这可能会比Map Reduce快,但另一种方法是每隔一段时间使用Map Reduce更新一次汇总集合,然后从中挑选出来。这意味着结果不会实时(可能延迟5分钟),但速度会非常快。

2

不完全是你开的结果,但实际上处于一种MongoDB的方式:

db.cars.aggregate([ 
    { "$group": { 
     "_id": { 
      "name": "$Name", 
      "type": "$Car" 
     }, 
     "Country": { "$first": "$Country" }, 
     "CarCount": { "$sum": 1 }, 
     "TotalPrice": { "$sum": "$Price" } 
    }}, 
    { "$group": { 
     "_id": "$_id.name", 
     "cars": { 
      "$push": { 
       "type": "$_id.type", 
       "country": "$Country", 
       "carCount": "$CarCount", 
       "TotalPrice": "$TotalPrice" 
      } 
     }, 
     "TotalPrice": { "$sum": "$TotalPrice" } 
    }} 
]) 

它给你:

{ 
    "_id" : "Smith", 
    "cars" : [ 
      { 
        "type" : "BMW", 
        "country" : "One", 
        "carCount" : 1, 
        "TotalPrice" : 200 
      }, 
      { 
        "type" : "Volvo", 
        "country" : "One", 
        "carCount" : 1, 
        "TotalPrice" : 100 
      } 
    ], 
    "TotalPrice" : 300 
} 
{ 
    "_id" : "Joe", 
    "cars" : [ 
      { 
        "type" : "KIA", 
        "country" : "Two", 
        "carCount" : 2, 
        "TotalPrice" : 200 
      }, 
      { 
        "type" : "Romeo", 
        "country" : "Two", 
        "carCount" : 1, 
        "TotalPrice" : 50 
      } 
    ], 
    "TotalPrice" : 250 
} 
+0

嘿,mayabe我也可以在汽车中输入{type:'Total'},然后放松结果以获得完全匹配的集合。那可能吗? –

+0

@RustemMustafin没有像我一样遇到同样的问题,如果你有一辆车由同一个人组成的两个不同的国家这些总数不匹配 – Sammaye

+0

@Sammaye这是有效的,因为我说'每个人都拥有在单一国家的汽车# –