node.js - mongodb使用aggregate统计最大值并且返回完整信息
天蓬老师
天蓬老师 2017-04-17 16:09:41
0
1
625
[
    {
        "_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
            }
        ]
天蓬老师
天蓬老师

欢迎选择我的课程,让我们一起见证您的进步~~

reply all(1)
Ty80

I wrote an ugly statement to meet the needs, for reference:

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}}    
           ])

If this query needs to be used frequently, it is recommended to consider modifying the Data Model.

Love MongoDB! Have Fun!

------------------------Gorgeous separator--------------------- ----------

MongoDB Chinese community has many offline activities, please click below:

2017 Huashan Sword Discussion|MongoDB Chinese Community

Hangzhou Station is coming in March! ! ! Interested friends please sign up quickly! ! !

Latest Downloads
More>
Web Effects
Website Source Code
Website Materials
Front End Template