在MongoDb中按15分钟的时间间隔分组结果
我有一个像这样的“状态”收藏-在MongoDb中按15分钟的时间间隔分组结果,mongodb,mongodb-query,aggregation-framework,Mongodb,Mongodb Query,Aggregation Framework,我有一个像这样的“状态”收藏- { _id: ObjectId("545a0b63b03dbcd1238b4567"), status: 1004, comment: "Rem dolor ipsam placeat omnis non. Aspernatur nobis qui nisi similique.", created_at: ISODate("2014-11-05T11:34:59.804Z") }, { _id: ObjectId("545
{
_id: ObjectId("545a0b63b03dbcd1238b4567"),
status: 1004,
comment: "Rem dolor ipsam placeat omnis non. Aspernatur nobis qui nisi similique.",
created_at: ISODate("2014-11-05T11:34:59.804Z")
},
{
_id: ObjectId("545a0b66b03dbcd1238b4568"),
status: 1001,
comment: "Sint et eos vero ipsa voluptatem harum. Hic unde voluptatibus et blanditiis quod modi.",
created_at: ISODate("2014-11-05T11:35:02.814Z")
}
....
....
我需要从该集合中按15分钟的间隔对结果进行分组。有几种方法可以做到这一点 第一个是with,它允许您剖析文档中的“日期”值。特别是将“分组”作为主要目的:
db.collection.aggregate([
{“$组”:{
“_id”:{
“年”:{“$year”:“$created_at”},
“dayOfYear”:{“$dayOfYear”:“$created_at”},
“小时”:{“$hour”:“$created_at”},
“间隔”:{
“$subtract”:[
{“$minute”:“$created_at”},
{“$mod”:[{“$minute”:“$created_at”},15]}
]
}
}},
“计数”:{“$sum”:1}
}}
])
第二种方法是使用一个小技巧,当从另一个日期对象减去一个日期对象(或其他直接的数学运算)时,结果是一个数值,表示两个对象之间的历元时间戳毫秒。因此,只要使用历元日期,就可以得到历元毫秒表示。然后对间隔使用日期数学:
db.collection.aggregate([
{“$组”:{
“_id”:{
“$subtract”:[
{“$subtract”:[“$created_at”,新日期(“1970-01-01”)],
{“$mod”:[
{“$subtract”:[“$created_at”,新日期(“1970-01-01”)],
1000 * 60 * 15
]}
]
},
“计数”:{“$sum”:1}
}}
])
因此,这取决于分组间隔的输出格式。两者基本上表示相同的东西,并且有足够的数据在代码中重新构造为“日期”对象
您可以在分组\u id
之后的“分组运算符”部分中添加任何其他内容。我只是用基本的“计数”例子来代替你自己关于你真正想做什么的任何真实陈述
MongoDB 4.x及以上版本 自最初编写日期聚合运算符以来,对其进行了一些添加,但在MongoDB 4.0中,将出现实际的“类型转换”,而不是使用BSON日期转换完成的基本数学技巧 例如,我们可以在此处使用和作为新助手:
db.collection.aggregate([
{“$组”:{
“_id”:{
“$toDate”:{
“$subtract”:[
{“$toLong”:“$created_at”},
{“$mod”:[{“$toLong”:“$created_at”},1000*60*15]}
]
}
},
“计数”:{“$sum”:1}
}}
])
这稍微短了一点,并且在定义管道时不需要将“epoch”值的外部BSON日期定义为常量,因此它对于所有语言实现都非常一致
这只是用于类型转换的两个“helper”方法,它们都与该方法相关联,该方法是一种“更长”的实现形式,允许对null
或转换中的错误进行自定义处理
通过这种转换,甚至可以从主键的ObjectId
获取Date
信息,因为这将是“创建”日期的可靠来源:
db.collection.aggregate([
{“$组”:{
“_id”:{
“$toDate”:{
“$subtract”:[
{“$toLong”:{“$toDate”:“$_id”},
{“$mod”:[{“$toLong”:{“$toDate”:“$\u id”},1000*60*15]}
]
}
},
“计数”:{“$sum”:1}
}}
])
因此,这种转换的“铸造类型”可以是非常强大的工具
警告-ObjectId
值仅限于内部时间值的精度,该值构成允许转换的部分数据。实际插入的“时间”很可能取决于正在使用的驾驶员。如果需要精度,仍然建议使用离散的BSON Date字段,而不是依赖ObjectId
值
有几种方法可以做到这一点 第一个是with,它允许您剖析文档中的“日期”值。特别是将“分组”作为主要目的:
db.collection.aggregate([
{“$组”:{
“_id”:{
“年”:{“$year”:“$created_at”},
“dayOfYear”:{“$dayOfYear”:“$created_at”},
“小时”:{“$hour”:“$created_at”},
“间隔”:{
“$subtract”:[
{“$minute”:“$created_at”},
{“$mod”:[{“$minute”:“$created_at”},15]}
]
}
}},
“计数”:{“$sum”:1}
}}
])
第二种方法是使用一个小技巧,当从另一个日期对象减去一个日期对象(或其他直接的数学运算)时,结果是一个数值,表示两个对象之间的历元时间戳毫秒。因此,只要使用历元日期,就可以得到历元毫秒表示。然后对间隔使用日期数学:
db.collection.aggregate([
{“$组”:{
“_id”:{
“$subtract”:[
{“$subtract”:[“$created_at”,新日期(“1970-01-01”)],
{“$mod”:[
{“$subtract”:[“$created_at”,新日期(“1970-01-01”)],
1000 * 60 * 15
]}
]
},
“计数”:{“$sum”:1}
}}
])
因此,这取决于分组间隔的输出格式。两者基本上表示相同的东西,并且有足够的数据在代码中重新构造为“日期”对象
您可以在分组\u id
之后的“分组运算符”部分中添加任何其他内容。我只是用基本的“计数”例子来代替你自己关于你真正想做什么的任何真实陈述
MongoDB 4.x及以上版本 自最初编写以来,对日期聚合操作符进行了一些添加,但从MongoDB 4.0开始,将出现实际的“类型转换”
db.collection.aggregate([
{$match: {created_at:{$exists:1}}},
{$group: {
_id: {$add:[
{$dayOfYear: "$created_at" },
{$multiply: [{$year: "$created_at"}, 1000]}
]},
count: {$sum: 1 }
}},
{$sort:{_id:-1}}
])
db.collection.aggregate([
{ "$group": {
"_id": {
"$toDate": {
"$subtract": [
{ "$toLong": { "$toDate": "$_id" } },
{ "$mod": [ { "$toLong": { "$toDate": "$_id" } }, 1000 * 60 * 15 ] }
]
}
},
"count": { "$sum": 1 }
}}
])