如何聚合两个嵌套文档?

时间:2013-05-13 15:10:06

标签: mongodb mongoid

由于视频已嵌入多个日期,而日期已嵌入多个国家/地区。使用聚合框架,我如何获得所有likes_count的总数?

我有以下结构:

{ "_id" : ObjectId( "5190fbbc72357e713900001b" ),
  "dates" : [ 
    { "_id" : ObjectId( "5190fbbc72357e713900001c" ),
      "countries" : [ 
        { "_id" : ObjectId( "5190fbbc72357e713900001d" ),
          "unique_views_count" : 500,
          "non_unique_views_count" : 1000,
          "likes_count" : 1,
          "comments_count" : 1,
          "iso_two_letter_country_code" : "US",
          "country_name" : "United States" }, 
        { "_id" : ObjectId( "5190fbbc72357e713900001e" ),
          "unique_views_count" : 300,
          "non_unique_views_count" : 777,
          "likes_count" : 0,
          "comments_count" : 0,
          "iso_two_letter_country_code" : "UK",
          "country_name" : "United Kingdom" } ],
      "date" : 20130513 } ],
  "video_id" : 1 }

到目前为止,我已经尝试过,但无济于事:

Video.collection.aggregate(
  { '$unwind' => '$dates.countries'},
  {
    '$group' => {
      '_id' => '$_id'
      'likes' => { '$sum' => '$dates.countries.likes_count' }
    }
  }
)

1 个答案:

答案 0 :(得分:1)

这是一种在文档的likes_count(来自MongoDB shell)上分组时获得_id总数的方法:

db.Videos.aggregate(
    {'$unwind': '$dates'}, 
    {'$unwind': '$dates.countries'}, 
    {$project: 
        { _id: 1, 
         likes_count: '$dates.countries.likes_count'}}, 
    {$group: 
        { _id : '$_id', 
          total_likes: { $sum: '$likes_count'}}})

关键是要分多步完成:

  1. 首先展开日期数组
  2. 然后,展开每个国家/地区的国家/地区数组
  3. 接下来,将likes_count映射到新属性以便于访问
  4. 最后,对_id进行分组,并将所有likes的总和加上total_likes
  5. 这给出了以下结果:

    {
        "result" : [{
            "_id" : ObjectId("5190fbbc72357e713900001b"),
            "total_likes" : 1
        }],
        "ok" : 1
    }
    

    如果您想对date字段进行分组,则需要将其包含在投影中,然后在管道中对其进行分组:

    db.so.aggregate(
        {'$unwind': '$dates'},
        {'$unwind': '$dates.countries'}, 
        {$project: 
            { _id: 1, 
              date: '$dates.date', 
              likes_count: '$dates.countries.likes_count'}},
        {$group: 
            { _id : '$date', 
              total_likes: { $sum: '$likes_count'}}})
    

    与上述基本步骤相同,但此时,date包含在投影中,然后用作group _id

    如果您想在特定日期匹配,请添加:

    { $match : { 'date' : 20130512 } } 
    

    在上面的例子中投影后的管道。