Mongodb 如何将数字1格式化为字符串;01“;用于聚合?

Mongodb 如何将数字1格式化为字符串;01“;用于聚合?,mongodb,mongodb-query,aggregation-framework,Mongodb,Mongodb Query,Aggregation Framework,我正在尝试根据文档中的日期字段以“YYYYMMDD”的形式创建聚合键。但是,使用$month和$dayOfMonth运算符,我只返回数字,没有将它们格式化为前导零的方法(此外,我无法连接数字) 我更喜欢聚合而不是Map/Reduce,因为后者具有阻塞性。有什么想法吗?基本上,您可以使用运算符通过一些条件连接字符串,以及处理转换: “天”:{ “$concat”:[ {“$substr”:[{“$year”:“$date”},0,4]}, {“$cond”:[ {“$lte”:[{“$month”

我正在尝试根据文档中的日期字段以“YYYYMMDD”的形式创建聚合键。但是,使用
$month
$dayOfMonth
运算符,我只返回数字,没有将它们格式化为前导零的方法(此外,我无法连接数字)

我更喜欢聚合而不是Map/Reduce,因为后者具有阻塞性。有什么想法吗?

基本上,您可以使用运算符通过一些条件连接字符串,以及处理转换:

“天”:{
“$concat”:[
{“$substr”:[{“$year”:“$date”},0,4]},
{“$cond”:[
{“$lte”:[{“$month”:“$date”},9]},
{“$concat”:[
“0”{“$substr”:[{“$month”:“$date”},0,2]}
]},
{“$substr”:[{“$month”:“$date”},0,2]}
]},
{“$cond”:[
{“$lte”:[{“$dayOfMonth”:“$date”},9]},
{“$concat”:[
“0”{“$substr”:[{“$dayOfMonth”:“$date”},0,2]}
]},
{“$substr”:[{“$dayOfMonth”:“$date”},0,2]}
]}
]
}
如果要按“天”进行聚合,另一种方法是只使用日期数学中的“历元”值:

“天”:{
“$subtract”:[
{“$subtract”:[“$date”,新日期(“1970-01-01”)],
{“$mod”:[
{“$subtract”:[“$date”,新日期(“1970-01-01”)],
1000 * 60 * 60 * 24
]}
]
}
对两个日期对象执行的任何日期数学操作都会导致历元毫秒数的差异。因此,使用纪元日期作为日期对象,以便转换。结果值是时间戳值的“day”,可以在处理结果时反馈以创建日期对象


可以说,您可以在后期处理中使用和结果做同样的事情,因为这些也足以在客户端处理中重新构成日期对象

虽然Neil的答案确实有效,但我觉得它相当不令人满意;它很难阅读,很难维护,而且速度很慢。假设您从某个日期获取值(如OP中所述);如果您使用的是mongo 3.0或更高版本,使用是最好的方法,但是如果您使用的是较早的版本(如我),我认为您最好只从日期字段中读取您想要的字符串部分(因为它们是零填充的):

这在我的例子中尤其有效,我只想得到
(这是使用@Neil的解决方案的一个正确的痛苦,因为我想将两个数字归零),但这种方法变得很简单:
formattedTime:{$substr:[“$timestamp”,11,5]}


当然,为了提高可读性,我建议用一些命名常量替换幻数。

谢谢!这既可怕又可怕。所以$substr会自动将数字转换为字符串,但$concat不会。这里还有改进的余地。@Marian是的。令人讨厌和可怕的东西,不断威胁着不受支持。为什么我真的不确定。但是,真正尝试看看其他方法,让您的“日期”格式在您想要的方式在您的最终结果。后期处理是一个更好的方法。我先有一个多部分的密钥,但按它的部分排序并没有达到我预期的效果。现在它工作得很好。让我们看看它能持续多久。这应该是最新MongoDB版本的公认答案:它是一个简洁明了的解决方案。
formattedTime: {
    $concat: [
        { $substr: ["$timestamp", 0, 4] },
        { $substr: ["$timestamp", 5, 2] },
        { $substr: ["$timestamp", 8, 2] }
    ]
}