我有一个这样的集合:
{'speed':45, 'time':1446271000},
{'speed':45, 'time':1446271001},
{'speed':63, 'time':1446271002},
{'speed':68, 'time':1446271003},
{'speed':70, 'time':1446271004},
{'speed':59, 'time':1446271005},
{'speed':55, 'time':1446271006},
{'speed':61, 'time':1446271007},
{'speed':62, 'time':1446271008},
{'speed':63, 'time':1446271009},
{'speed':67, 'time':1446271010}
我想总结高速(速度> = 60)记录,因此结果应如下所示:
{'speed':63,'duration':2,'start': 1446271002,'end': 1446271004}
{'speed':61,'duration':3,'start': 1446271007,'end': 1446271010}
我该如何实现这个目标?
答案 0 :(得分:2)
使用以下聚合管道执行初始 $match
来过滤掉小于60的文档。
下一个管道步骤使用 $sort
运算符按时间字段重新排序文档,这是下一步所必需的,即 $group
管道。在这里,您可以通过使用 $first
和 $last
累加器运算符来获取开始和结束字段。第一次和最后一次按速度字段对文档进行分组作为键。
最后一个管道步骤 $project
使用 $subtract
算术运算符创建附加字段,持续时间,顾名思义,它减去来自start
次的end
。最终的管道如下所示:
db.test.aggregate([
{ "$match": { "speed": { "$gte": 60 } } },
{ "$sort": { "time": 1 } },
{
"$group": {
"_id": "$speed",
"start": { "$first": "$time" },
"end": { "$last": "$time" }
}
},
{
"$project": {
"_id": 0,
"speed": "$_id",
"duration": { "$subtract": [ "$end", "$start" ] },
"start": 1,
"end": 1
}
}
])
示例输出:
/* 0 */
{
"result" : [
{
"start" : 1446271010,
"end" : 1446271010,
"speed" : 67,
"duration" : 0
},
{
"start" : 1446271007,
"end" : 1446271007,
"speed" : 61,
"duration" : 0
},
{
"start" : 1446271008,
"end" : 1446271008,
"speed" : 62,
"duration" : 0
},
{
"start" : 1446271004,
"end" : 1446271004,
"speed" : 70,
"duration" : 0
},
{
"start" : 1446271003,
"end" : 1446271003,
"speed" : 68,
"duration" : 0
},
{
"start" : 1446271002,
"end" : 1446271009,
"speed" : 63,
"duration" : 7
}
],
"ok" : 1
}
答案 1 :(得分:0)
我发布这个是因为现有的答案会向管道添加不必要的$sort
阶段,这将导致性能下降。
您需要使用$gte
运算符过滤掉speed
为$match
的集合中的所有文档,然后按“速度”过滤$group
您的文档并使用{ {3}}和$min
累加器运算符分别返回不同组的“时间”的最小值和最大值。从那里你需要$max
离子阶段使用$project
运算符来计算“持续时间”。当然,$subtract
方法可以访问.aggregate()
。
db.collection.aggregate([
{ "$match": {
"speed": { "$gte": 60 }
}},
{ "$group": {
"_id": "$speed",
"duration": { "$sum": 1 },
"start": { "$min": "$time" },
"end": { "$max": "$time" }
}},
{ "$project": {
"speed": "$_id",
"_id": 0,
"duration": { "$subtract": [ "$end", "$start" ] },
"start": 1,
"end": 1
}}
])
哪个收益率:
{ "start" : 1446271010, "end" : 1446271010, "speed" : 67, "duration" : 0 }
{ "start" : 1446271008, "end" : 1446271008, "speed" : 62, "duration" : 0 }
{ "start" : 1446271007, "end" : 1446271007, "speed" : 61, "duration" : 0 }
{ "start" : 1446271004, "end" : 1446271004, "speed" : 70, "duration" : 0 }
{ "start" : 1446271003, "end" : 1446271003, "speed" : 68, "duration" : 0 }
{ "start" : 1446271002, "end" : 1446271009, "speed" : 63, "duration" : 7 }