【问题标题】:MongoDb How to group by month and year from stringMongoDb如何从字符串按月和年分组
【发布时间】:2015-03-06 08:00:54
【问题描述】:

我在集合中有字段 dateStr

  {  ....    "dateStr" : "07/01/2020" .... }
  {  ....    "dateStr" : "07/01/1970"   .... }

我想从 dateStr 字段按月和年分组

我试过了

    db.collection.aggregate( 
       {$project : { 
              month : {$month : new Date("$dateStr")}, 
              year : {$year :  new Date("$dateStr")}
          }}, 
        {$group : { 
                _id : {month : "$month" ,year : "$year" },  
              count : {$sum : 1} 
        }})

输出:

{
"result" : [ 
        {
            "_id" : {
                "month" : 1,
                "year" : 1970
            },
            "count" : 2
        }
    ],
    "ok" : 1
}

但我有两年 1970,2020。为什么我得到单曲?

【问题讨论】:

    标签: mongodb mongodb-query aggregation-framework


    【解决方案1】:

    您不能在任何其他属于 Date 对象本身的东西上使用 date aggregation operators。您最终的最佳选择是将这些“字符串”转换为正确的 Date 对象,以便您可以在此操作和将来的操作中正确查询。

    也就是说,如果你的“字符串”总是有一个共同的结构,那么有一种方法可以使用aggregation framework 工具来做到这一点。它需要大量的操纵思想,这并不能使这成为处理问题的“最佳”方法。但是使用“两位数”的集合结构和一致的分隔符,$substr 运算符可以做到这一点:

    db.collection.aggregate([
       { "$group": {
           "_id": {
               "year": { "$substr": [ "$dateStr", 7, 4 ] },
               "month": { "$substr": [ "$dateStr", 4, 2 ] }
           },
           "count": { "$sum": 1 }
       }}
    ])
    

    所以 JavaScript 转换在聚合框架内不起作用。您始终可以根据“客户端代码”评估将输入“馈送”到管道,但聚合过程本身不会评估任何代码。就像基本的查询引擎一样,这一切都是基于使用“本地运算符”指令来完成工作的“数据结构”实现。

    您不能在聚合管道中将字符串转换为日期。您应该使用真正的 BSON Date 对象,但如果存在可以以“词法顺序”呈现的一致格式,则可以使用字符串。

    我仍然建议您尽快将这些转换为BSON Dates。请注意,“ISODate”或 UTC 值是用不同的字符串形式构造的。即:

    new Date("2020-01-07")
    

    采用“yyyy-mm-dd”格式。至少对于 JavaScript 调用而言。

    【讨论】:

    • 谢谢。这很有帮助。这是工作 。我同意你的观点。我将根据 bson 日期对象进行适当的分组。
    • @Ramesh 好消息。然后您可以使用date aggregation operators,如原始代码示例中所示。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2021-03-10
    • 2018-08-29
    • 2017-03-02
    • 2012-12-10
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多