如何在mongodb中通过日期聚合组从数组中获取最后两个值?
我从这个集合中得到了输出如何在mongodb中通过日期聚合组从数组中获取最后两个值?,mongodb,mongoose,mongodb-query,aggregation-framework,Mongodb,Mongoose,Mongodb Query,Aggregation Framework,我从这个集合中得到了输出 UserActivity.aggregate([ { $match: { user_id: {$in: user_id}, "tracker_id": {$in:getTrackerId}, date: { $gte: req.app.locals._mongo_date(req.params[3]),$lte: req.app.loc
UserActivity.aggregate([
{
$match: {
user_id: {$in: user_id},
"tracker_id": {$in:getTrackerId},
date: { $gte: req.app.locals._mongo_date(req.params[3]),$lte: req.app.locals._mongo_date(req.params[4]) }
}
},
{ $sort: {date: 1 } },
{ $unwind: "$duration" },
{
$group: {
_id: {
tracker: '$tracker_id',
$last:"$duration",
year:{$year: '$date'},
month: {$month: '$date'},
day: {$dayOfMonth: '$date'}
},
resultData: {$sum: "$duration"}
}
},
{
$group: {
_id: {
year: "$_id.year",
$last:"$duration",
month:"$_id.month",
day: "$_id.day"
},
resultData: {
$addToSet: {
tracker: "$_id.tracker",
val: "$resultData"
}
}
}
}
], function (err,tAData) {
tAData.forEach(function(key){
console.log(key);
});
});
但我需要此集合的输出,我想从每个集合中获取最后两条记录:
{ _id: { year: 2015, month: 11, day: 1 },
resultData:[ { tracker: 55d2e6b043d77c0877105397, val: 60 },
{ tracker: 55d2e6b043d77c0877105397, val: 75 },
{ tracker: 55d2e6b043d77c0877105397, val: 25 },
{ tracker: 55d2e6b043d77c0877105397, val: 21 } ] }
{ _id: { year: 2015, month: 11, day: 2 },
resultData:[ { tracker: 55d2e6b043d77c0877105397, val: 100 },
{ tracker: 55d2e6b043d77c0877105397, val: 110 },
{ tracker: 55d2e6b043d77c0877105397, val: 40 },
{ tracker: 55d2e6b043d77c0877105397, val: 45 } ] }
您的语句中有明显的语法错误,因为这不是一个有效的用法,但我怀疑这与您“尝试”做什么有关,而不是与您使用什么来获得实际结果有关 对于聚合框架来说,使用“最佳
n
值”获得结果有点困难。我对基本情况有一个较长的解释,但归根结底,聚合框架缺乏基本工具,无法按照您想要的分组键进行“有限”分组
做得不好 对于你想要返回的结果的数量来说,这种可怕的方法是非常“迭代”的。它基本上意味着将所有内容都放入一个数组,然后使用诸如(反向排序后)之类的运算符从堆栈中返回结果,然后从结果中“过滤”该结果(认为是数组弹出或移位操作),然后再次执行该操作以获得下一个结果 基本上,这是一个
2
迭代示例:
UserActivity.aggregate(
[
{“$match”:{
“用户id”:{“$in”:用户id},
“tracker_id”:{“$in”:gettrackrid},
“日期”:{
“$gte”:起始日期,
“$lt”:结束日期
}
}},
{“$unwind”:“$duration”},
{“$组”:{
“_id”:{
“跟踪器id”:“$tracker\u id”,
“日期”:{
“$add”:[
{“$subtract”:[
{“$subtract”:[“$date”,新日期(0)],
{“$mod”:[
{“$subtract”:[“$date”,新日期(0)],
1000 * 60 * 60 * 24
]}
]},
新日期(0)
]
},
“val”:{“$sum”:“$duration”}
}
}},
{“$sort”:{“_id”:1,“val”:-1},
{“$组”:{
“\u id”:“$\u id.date”,
“结果数据”:{
“$push”:{
“跟踪器id”:“$\u id.跟踪器id”,
“val”:“$val”
}
}
}},
{“$REWIND”:“$resultData”},
{“$组”:{
“\u id”:“$\u id”,
“last”:{“$first”:“$resultData”},
“resultData”:{“$push”:“$resultData”}
}},
{“$REWIND”:“$resultData”},
{“$redact”:{
“if”:{“$eq”:[“$resultData”,“$last”]},
“然后”:“$$PRUNE”,
“其他”:“$$KEEP”
}},
{“$组”:{
“\u id”:“$\u id”,
“last”:{“$first”:“$last”},
“secondLast”:{“$first”:“$resultData”}
}},
{“$project”:{
“结果数据”:{
“$map”:{
“输入”:[0,1],
“as”:“索引”,
“在”:{
“$cond”:{
“if”:{“$eq”:[“$$index”,0]},
“$last”,
}
}
}
}
}}
],
函数(err、tAData){
log(JSON.stringify(tAData,未定义,2))
}
);
还可以将日期输入简化为管道代码之前的预定义日期对象值,即startDate
和endDate
。但这里的原则表明,这不是一种性能或非常可扩展的方法,主要是因为需要将所有结果放入一个数组中,然后处理这些结果以仅获取值
做得更好 更好的方法是为范围内的每个日期向服务器发送聚合查询,因为日期是您想要的最终键。由于您一次只返回每个“键”,因此很容易应用来限制响应 理想的情况是并行执行这些查询,然后组合它们。幸运的是,节点库提供了一个or,特别是
async.mapLimit
,它正好执行此功能:
注意:您不希望async.mapSeries
获得最佳性能,因为查询是“按顺序串行执行”的,这意味着服务器上一次只发生一个操作。结果是按数组排序的,但需要更长的时间。客户端排序在这里更有意义
var-dates=[],
返回限制=2,
一天=1000*60*60*24;
//为范围内的每个日期生成一个数组
对于(
var myDate=起始日期;
myDate{ _id: { year: 2015, month: 11, day: 1 },
resultData:[ { tracker: 55d2e6b043d77c0877105397, val: 25 },
{ tracker: 55d2e6b043d77c0877105397, val: 21 } ] }
{ _id: { year: 2015, month: 11, day: 2 },
resultData:[ { tracker: 55d2e6b043d77c0877105397, val: 40 },
{ tracker: 55d2e6b043d77c0877105397, val: 45 } ] }