问题描述
[ {'_id' : ObjectId('58ad2f4b52823f000f0ea3f3'),'serverPortCount' : { 'port1883' : 10, 'port80' : 10},'serverIP' : '192.168.0.15','statsTime' : 1487744242702,'creatTime' : 1487744843961,'statsType' : 1,'__v' : 0 }, {'_id' : ObjectId('58ad2f4b52823f000f0ea3f4'),'serverPortCount' : { 'port1883' : 20, 'port80' : 20},'serverIP' : '192.168.0.15','statsTime' : 1487744302716,'creatTime' : 1487744843962,'statsType' : 1,'__v' : 0 }, {'_id' : ObjectId('58ad2f4b52823f000f0ea3f5'),'serverPortCount' : { 'port1883' : 30, 'port80' : 30},'serverIP' : '192.168.0.14','statsTime' : 1487744362730,'creatTime' : 1487744843963,'statsType' : 1,'__v' : 0 }]
我有一组数据,数据结构是上面的那个样子,然后现在想统计出来某个时间段内的serverIP的serverPortCount里面的port1883+port80最大的记录,期望的结果是
我现在的做法使用使用aggregate
WsStats.aggregate().match({ statsType:1, statsTime:{ $gte : startTime, $lt : endTime }}).group({ _id: '$serverIP', maxCount: { $max: { $add: [ '$serverPortCount.port80', '$serverPortCount.port1883' ] } }}).project({ maxCount:1, serverIP:'$_id'}).exec(callback);
现在是可以统计出来最大数,结果如下
[{ maxCount:40,'serverIP' : '192.168.0.15', }, {maxCount:60,'serverIP' : '192.168.0.14' }]
但是我想知道完整的记录,期望结果如下:
[{'_id' : ObjectId('58ad2f4b52823f000f0ea3f4'),'serverPortCount' : { 'port1883' : 20, 'port80' : 20},maxCount:40,'serverIP' : '192.168.0.15','statsTime' : 1487744302716,'statsType' : 1 }, {'_id' : ObjectId('58ad2f4b52823f000f0ea3f5'),'serverPortCount' : { 'port1883' : 30, 'port80' : 30},maxCount:40,'serverIP' : '192.168.0.14','statsTime' : 1487744362730,'statsType' : 1 }]
问题解答
回答1:写了一个难看一点的语句满足需求,供参考:
db.test.aggregate([ {$project : { '_id' : 1 , serverPortCount : 1 , serverIP : 1 , statsTime : 1 , statsType : 1 , count : { $add: [ '$serverPortCount.port80', '$serverPortCount.port1883' ]}} }, {$sort : { serverIP : 1 , count : -1 }}, {$group : {'_id' : '$serverIP', 'ObjectId' : { $first : '$_id'}, serverPortCount : { $first : '$serverPortCount'}, 'maxcount' : { $first : '$count' }, statsTime : {$first : '$statsTime'}, statsType : {$first : '$statsType'}}}, {$project : {'_id' : '$ObjectId','serverPortCount' : 1,'maxcount' : 1,'serverIP' : '$_id','statsTime' : 1,'statsType' : 1}} ])
如果这个查询经常需要用到,建议考虑修改Data Model。
Love MongoDB! Have Fun!
------------------------华丽的分割符--------------------------------
MongoDB中文社区线下活动缤纷,请猛戳下方:
2017华山论剑|MongoDB中文社区
三月份杭州站在即!!! 感兴趣的朋友火速报名!!!