如何在MongoDB中按月份的前半部分或后半部分(两周)对日期进行分组

时间:2019-06-13 18:07:17

标签: mongodb aggregation-framework

使用以下数据结构,如何使用mongoDB(v3.4)聚合框架每15天对信息分组一次?

{
    "_id" : ObjectId("5cb10a201e20af7503305fea"),
    "user" : ObjectId("5b21240c4e71161fdd40b27c"),
    "version" : NumberLong(2),
    "value" : 42,
    "itemRef" : ObjectId("5cb10a201e20af7503305fe9"),
    "status" : "ACCEPTED",
    "date" : ISODate("2019-04-13T11:00:00.466Z")
}

所需的输出将是:

[date: 2019/01/01, totalValue:15],
[date: 2019/01/16, totalValue:5],
[date: 2019/02/01, totalValue:25],
[date: 2019/02/16, totalValue:30]

1 个答案:

答案 0 :(得分:0)

我发现使用mongoDB 3.4解决此问题的方法是使用$ cond + $ dayOfMonth定义此日期在月份的哪个部分。

db.contract.aggregate(
[
  {$match:{...queryGoesHere...}},
  {$project:
    {dateText:
      {$cond:
        [
          {$lte:[{$dayOfMonth:$date},15]},
          ['$dateToString': ['format': '%Y-%m-01', 'date': '$date']], 
          ['$dateToString': ['format': '%Y-%m-16', 'date': '$date']]
        ]
      }
     value:'$value'
    }
  },
  {$group:
    {
      _id:'$dateText',
      total:{'$sum':1}
    }
  }
]

解决方案在“ dateText”的投影中,它首先使用$ cond确定日期是在月的第一部分还是第二部分。它使用'$ dayOfMonth'来确定该值,该值将返回月份中的日期。如果它小于或等于15,则使用'$ dateToString'来按Year-month-01格式化日期,否则将其格式化为Year-month-16。

希望这对以后的人有帮助。