node.js - mongodb使用aggregate统计最大值并且返回完整信息

查看:379
本文介绍了node.js - mongodb使用aggregate统计最大值并且返回完整信息的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

问 题

[
    {
        "_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
            }
        ]

解决方案

写了一个难看一点的语句满足需求,供参考:

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中文社区

三月份杭州站在即!!! 感兴趣的朋友火速报名!!!

这篇关于node.js - mongodb使用aggregate统计最大值并且返回完整信息的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆