将ISO日期转换为yyyy-mm-dd格式

时间:2016-06-26 14:51:18

标签: mongodb mongodb-query aggregation-framework

给定集合(#name:users)结构:

{
"_id" : ObjectId("57653dcc533304a40ac504fc"),
"username" : "XYZ",
"followers" : [ 
    {
        "count" : 31,
        "ts" : ISODate("2016-06-17T18:30:00.996Z")
    }, 
    {
        "count" : 31,
        "ts" : ISODate("2016-06-18T18:30:00.288Z")
    }
]
}

我想根据用户名字段查询此集合,并在' yyyy-mm-dd'中返回ts。格式。 预期产出:

{
"_id" : ObjectId("57653dcc533304a40ac504fc"),
"username" : "XYZ",
"followers" : [ 
    {
        "count" : 31,
        "date" : "2016-06-17"
    }, 
    {
        "count" : 31,
        "date" : "2016-06-18"
    }
]
}

我尝试过这样的事情:

db.users.aggregate([
{$match:{"username":"xyz"}},
{$project:{ "followers":{"count":1,
        "date":"$followers.ts.toISOString().slice(0,10).replace(/-/g,'-')"
          }}
}
])

但它似乎没有起作用。有人可以帮忙吗? 非常感谢。

2 个答案:

答案 0 :(得分:3)

考虑运行一个汇总管道,该管道允许您首先展平数据列表,使用 $dateToString 运算符投影新字段,然后重新组合展平的文档以获得所需的结果。

上述内容可以用三种不同的流水线显示:

db.users.aggregate([
    { "$match": { "username": "xyz" } },
    { "$unwind": "$followers" },
    {
        "$project": {
            "username": 1,
            "count": "$followers.count",
            "date": { "$dateToString": { "format": "%Y-%m-%d", "date": "$followers.ts" } }
        }
    },
    {
        "$group": {
            "_id": "$_id",
            "username": { "$first": "$username" },
            "followers": { "$push": {
                "count": "$count",
                "date": "$date"
            }}
        }
    }
])

使用MongoDB 3.4及更高版本,您可以使用新的 $addFields 管道步骤与 $map 一起创建数组字段而无需放松和分组:

db.users.aggregate([
    { "$match": { "username": "xyz" } },    
    {
        "$addFields": {
            "followers": { 
                "$map": { 
                    "input": "$followers", 
                    "as": "follower",
                    "in": { 
                        "count": "$$follower.count", 
                        "date": { 
                            "$dateToString": { 
                                "format": "%Y-%m-%d", 
                                "date": "$$follower.ts" 
                            }
                        } 
                    } 
                } 
            }
        }
    }
])

答案 1 :(得分:0)

最好和最简单的方法是使用$map运算符转换数组中的每个元素。当然,在“in”表达式中,您需要使用$dateToString使用format specifiers将“date”转换为字符串。

db.coll.aggregate(
    [ 
        { "$match": { "username": "XYZ" } }, 
        { "$project": { 
            "username": 1, 
            "followers": { 
                "$map": { 
                    "input": "$followers", 
                    "as": "f",
                    "in": { 
                        "count": "$$f.count", 
                        "date": { 
                            "$dateToString": { 
                                "format": "%Y-%m-%d", 
                                "date": "$$f.ts" 
                            }
                        } 
                    } 
                } 
            } 
        }}
    ]
)

产生:

{
    "_id" : ObjectId("57653dcc533304a40ac504fc"),
    "username" : "XYZ",
    "followers" : [
        {
            "count" : 31,
            "date" : "2016-06-17"
        },
        {
            "count" : 31,
            "date" : "2016-06-18"
        }
    ]
}