2013-12-18 76 views
3

我有大量的文档在蒙戈数据库的结构如下:复杂aggregate命令的MongoDB

{ 
    "_id" : { 
     "birthDate" : "1978-08-09", 
     "name" : "Peter" 
}, 
    "value" : { 
     "types" : { 
      "euro" : 90, 
      "unknown" : 2, 
      "dollar" : 3 
     } 
    } 
} 

并非所有的文件包含所有类型(即:他们有的只有euro或没有unknown领域)。

我想统计每个type对于具有集合框架的特定名称的出现次数。

我有这样的:

db.collection.aggregate({$match: {_id : {name:"John"}}}, {$group: {_id: '', euro: {$sum: '$value.types.euro'}, dollar: {$sum: '$value.types.dollar'}, unknown: {$sum: '$value.types.unknown'}}}) 

但它返回:

{ "result" : [ ], "ok" : 1 } 

我的问题是:我怎么能指望每个cointype特定name与蒙戈的总框架?难道是还可以得到一个列表的形式每一个名字:

"result" : [ 
    { 
     "name" : "Peter", 
     "dollar" : 1, 
     "euro" : 12, 
     "unknown" : 4 

    } 
] 

"result" : [ 
    { 
     "name" : "John", 
     "dollar" : 4, 
     "euro" : 10, 
     "unknown" : 3 

    } 
] 

我使用的MongoDB的Java驱动程序,所以如果答案是在Java代码中这将是完美的。

回答

3

您可以按名称&硬币计数使用下面的查询组:

db.collection.aggregate(
    {$group : {_id : "$_id.name", 
      dollar : {$sum : "$value.types.dollar"}, 
      euro : {$sum : "$value.types.euro"}, 
      unknown : {$sum : "$value.types.unknown"}}} 
) 

此外,如果你想找到硬币特定的人的数量,您可以使用下面的查询:

db.collection.aggregate(
    {$match : {"_id.name" : "John"}}, 
    {$group : {_id : "$_id.name", 
      dollar : {$sum : "$value.types.dollar"}, 
      euro : {$sum : "$value.types.euro"}, 
      unknown : {$sum : "$value.types.unknown"}}} 
) 
+0

这就是我一直在寻找的东西。 现在我想知道:是否有可能只采取出生日期在两个日期之间的结果?即与第一个请求完全相同的结果,但仅限于1980-07-05和1985-08-05 – user3083022

+0

之间的那些结果,您可以将$ match查询更新为{$ match:{“_id.name”:“John” ,“_id.birthDate”:{$ gte:“1980-07-05”,$ lte:“1985-08-05”}}} –

+0

不错,现在问题是日期实际上是这样存储的: ' ISODate( “1980-08-05T22:00:00Z”)'。这些$ gte似乎并没有真正的工作,我得到'{“result”'':'''''''''''''''''''''''当我更新$匹配时'{$ match'':''{“_id.name”'':''“John”,''“_id.birthDate”'':''{$ gte'':'''ISODate(“1980- 07-5“)',''$ lte'':'''ISODate(”1985-08-05“)'}}}' – user3083022

1

要计算每个cointype对于特定的name,您可以这样做:

db.collection.aggregate([ 
{ 
    $match: {'_id.name' : "John"} 
}, 
{ 
    $project: { 
     _id: 1, 
     euro: {$cond: [ { $eq: [ '$value.types.euro', undefined ]} , 0, 1 ]}, 
     dollar: {$cond: [ { $eq: [ '$value.types.dollar', undefined ]} , 0, 1 ]}, 
     unknown: {$cond: [ { $eq: [ '$value.types.unknown', undefined ]}, 0, 1 ]} 
    } 
}, 
{ 
    $group: {_id: "$_id.name", euro: {$sum: '$euro'}, dollar: {$sum: '$dollar'}, unknown: {$sum: '$unknown'}} 
} 
]) 
+0

这应该等于@parvin写的第二个查询吗?结果非常不同 – user3083022

+0

不,它不等同于@parvin写的第二个查询。我的查询使用_id.name ='John'计算每个类型(欧元,美元和未知)在所有文档中的存在次数。这不是该类型值的$总和。我希望很明显,我的英语不是很好:) – Anthonny

+0

好的,我明白了!那时我正在寻找@ parvin的更多。谢谢你 – user3083022