2016-06-07 129 views
0

我在我的收藏文件喜欢:查询嵌套数组中元素的总数 - 嵌入文档的MongoDB

{ 
    _id: 1, 
    activities: [ 
    { 
     activity_id: 1, 
     travel: [ 
     { 
      point_id: 1, 
      location: [-76.0,19.1] 
     }, 
     { 
      point_id: 2, 
      location: [-77.0,19.3] 
     } 
     ] 
    }, 
    { 
     activity_id: 2, 
     travel: [ 
     { 
      point_id: 3, 
      location: [-99.3,18.2] 
     } 
     ] 
    } 
    ] 
}, 
{ 
    _id: 2, 
    activities: [ 
    { 
     activity_id: 3, 
     travel: [ 
     { 
      point_id: 4, 
      location: [-75.0,11.1] 
     } 
     ] 
    } 
    ] 
} 

我能得到的活动总数,如下:

db.mycollection.aggregate(
    {$unwind: "$activities"}, 
    {$project: {count:{$add:1}}}, 
    {$group: {_id: null, number: {$sum: "$count" }}} 
) 

我得到(3个活动):

{ "result" : [ { "_id" : null, "number" : 3 } ], "ok" : 1 } 

问题:何我能获得所有旅行中的元素总数吗?

预期的结果:4元件

它们是:

{ 
    point_id: 1, 
    location: [-76.0,19.1] 
}, 
{ 
    point_id: 2, 
    location: [-77.0,19.3] 
}, 
{ 
    point_id: 3, 
    location: [-99.3,18.2] 
}, 
{ 
    point_id: 4, 
    location: [-75.0,11.1] 
} 
+1

其实这是和仍然像'db.mycollection.aggregate简单({“$组“:{”_id“:null,”total“:{”$ sum“:{”$ sum“:{”$ map“:{”input“:”$ activities“,”as“:”a“, “in”:{“$ size”:“$$ a.travel”}}}}}}})'。这是因为'$ sum'可以直接用于数组,也可以作为自MongoDB 3.2以来的累加器。通过您自己删除的答案,您目前的MongoDB版本似乎比这个要旧得多。 –

回答

1

可以很容易地通过使用双$unwind

例如变换文件

db.collection.aggregate([ 
    {$unwind: "$activities"}, 
    {$unwind: "$activities.travel"}, 
    {$group:{ 
    _id:null, 
    travel: {$push: { 
     point_id:"$activities.travel.point_id", 
     location:"$activities.travel.location"}} 
    }}, 
    {$project:{_id:0, travel:"$travel"}} 
]) 

这将发出非常接近你想要的输出格式:

{ 
    "travel" : [ 
     { 
      "point_id" : 1.0, 
      "location" : [ 
       -76.0, 
       19.1 
      ] 
     }, 
     { 
      "point_id" : 2.0, 
      "location" : [ 
       -77.0, 
       19.3 
      ] 
     }, 
     { 
      "point_id" : 3.0, 
      "location" : [ 
       -99.3, 
       18.2 
      ] 
     }, 
     { 
      "point_id" : 4.0, 
      "location" : [ 
       -75.0, 
       11.1 
      ] 
     } 
    ] 
} 

更新:

如果你只是想知道在整个集合旅行证件的总数,

试试看:

db.collection.aggregate([ 
    {$unwind: "$activities"}, 
    {$unwind: "$activities.travel"}, 
    {$group: {_id:0, total:{$sum:1}}} 
]) 

它会打印:

{ 
    "_id" : NumberInt(0), 
    "total" : NumberInt(4) 
} 

更新2:

OP希望基于在聚合框架某些属性过滤文件。这里有一个方法可以这样做:

db.collection.aggregate([ 
    {$unwind: "$activities"}, 
    {$match:{"activities.activity_id":1}}, 
    {$unwind: "$activities.travel"}, 
    {$group: {_id:0, total:{$sum:1}}} 
]) 

它将打印(基于样本文档):

{ "_id" : 0, "total" : 2 } 
+0

这是完美的,非常感谢.....我不知道双'$ unwind' –

+0

可能加入参数'{$ match:{“activities.activity_id”:1}}''所以我可以得到特定活动的旅行清单? .... 怎么做 ? –

+0

确实,你可以做到这一点。请参阅$匹配 – Saleem