【问题标题】:Mongo aggregate sum and group items by dateMongo 按日期汇总和分组项目
【发布时间】:2018-12-12 21:31:18
【问题描述】:

非常感谢您的宝贵时间。我正在研究一个我想对同一日期的项目求和的集合。考虑以下示例,这里我有两个文档,其中存储了 user_id 和播放事件。我想总结那些日期相同的文件。在我的情况下,2017-01-25 有两个结果,而 2017-01-26 只有一个。请查看预期结果。

{
    "_id" : ObjectId("58891b5656a961427e7b23c6"),
    "user_id" : 122,
    "played_event" : [ 
        {
            "date" : ISODate("2017-01-25T21:43:48.146Z"),
            "totalPlayed" : 0,
        }, 
        {
            "date" : ISODate("2017-01-26T22:26:03.273Z"),
            "totalPlayed" : 838,
        }, 
    ]
}

{
    "_id" : ObjectId("58891b5656a961427e7b23f3"),
    "user_id" : 130,
    "played_event" : [ 
        {
            "date" : ISODate("2017-01-25T21:43:48.146Z"),
            "totalPlayed" : 0,
        }, 
        {
            "date" : ISODate("2017-01-30T22:26:03.273Z"),
            "totalPlayed" : 838,
        }, 
    ]
}

预期结果

{
    "result" : [ 
        {
            "date" : "2017-01-25"
            "sum" : 2
        }, 
        {
            "date":"2017-01-26"
            "sum":1
        }, 
    ],
    "ok" : 1
}

我正在尝试使用以下代码

[{"$unwind":"$played_event"},{"$match":{"$and":[{"played_event.date":{"$lte":{"sec":1530766799,"usec":0},"$gte":{"sec":1530162000,"usec":0}}},{"game_id":1}]}},{"$match":{"user_id":{"$nin":[1,2]}}},{"$group":{"_id":"$user_id","total":{"$sum":"$played_event.totalPlayed"},"events":{"$push":"$played_event.date"}}},{"$project":{"_id":0,"user_id":"$_id","total":1,"events":1}}]

但它没有给我预期的结果,我在我的查询中总结了 totalPlayed,但目前不需要。

【问题讨论】:

    标签: mongodb aggregate


    【解决方案1】:

    您需要首先 $unwind "played_event" 然后您需要 $group 通过使用 $dateToString"date" 输入所需的格式

    db.collection.aggregate([
      { "$unwind": "$played_event" },
      { "$group": {
        "_id": {
          "$dateToString": {
            "format": "%Y-%m-%d",
            "date": "$played_event.date"
          }
        },
        "sum": { "$sum": 1 }
      }},
      { "$project": {
        "date": "$_id",
        "sum": 1,
        "_id": 0
      }}
    ])
    

    输出

    [
      {
        "date": "2017-01-30",
        "sum": 1
      },
      {
        "date": "2017-01-26",
        "sum": 1
      },
      {
        "date": "2017-01-25",
        "sum": 2
      }
    ]
    

    【讨论】:

      【解决方案2】:

      实现此目的的另一种方法。这个解决方案是我的首选,因为它更容易在 2 个任意日期之间计算,而不是按日期/月/年

      db.test2.aggregate([
              {
                  $unwind: {path : "$played_event"}
              },
              {
                  $project: { day: { $dateToString: { format: '%Y-%m-%d', date: '$played_event.date' } } }
              },
              {
                  $bucket: {
                      groupBy: "$day",
                      boundaries: [ "2017-01-25","2017-01-26","2017-01-27" ], //bucket is inclusive for start, exclusive for end
                      default: "other",
                      output: { count: { $sum: 1 } }
                  }
              },
          ]
      );
      

      输出:

       { 
          "_id" : "2017-01-25", 
          "count" : 2.0
      }
      { 
          "_id" : "2017-01-26", 
          "count" : 1.0
      }
      { 
          "_id" : "other", 
          "count" : 1.0
      }
      

      【讨论】:

        【解决方案3】:
        {
            'unwind' : '$played_event'
        },
        {
            '$group' : {
                _id : { $concat: [ { $year: "$date" }, "+", { $month: "$date" }, "+", { $dayOfMonth: "$date" }] }
        
                "sum" : { $sum : 1}
            }, 
        },
        {
            $match : {
                _id : { $in : ["2017-01-25", "2017-01-26"] }
            }
        },
        {
            $project : { _id : 0, "date" : "$_id", "sum" : 1
        }
        

        【讨论】:

          猜你喜欢
          • 2021-03-09
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2021-01-06
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多