首页 > 解决方案 > Mongo 返回两行而不是一

问题描述

$max在mongodb中遇到了一些问题。

我想只返回一个最大值uptime

查询隔离场景:

db.monitoraservicos.aggregate([
{"$match" : {"instancia" : "bat1"}

},
{"$group": {"_id": {
                    "instancia": "$instancia",
                    "uptime" :  {"$max" :"$uptime"},
                    "time": "$time"
                    }
           }
},
{"$project" : {
                "instancia" : "$_id.instancia",
                "uptime" : "$_id.uptime",
                "time" : "$_id.time",
                "_id" : 0
            }
},
{"$sort" : {"instancia" : 1}}
        ])

返回 :

/* 1 */
{
    "instancia" : "bat1",
    "uptime" : 86,
    "time" : ISODate("2019-09-26T13:37:37.000Z")
}

/* 2 */
{
    "instancia" : "bat1",
    "uptime" : 221,
    "time" : ISODate("2019-09-26T13:37:37.000Z")
}

我的期望:

   {
        "instancia" : "bat1",
        "uptime" : 221,
        "time" : ISODate("2019-09-26T13:37:37.000Z")
    }

谢谢

标签: mongodb

解决方案


请试试这个,还请查看我的评论以了解您的查询出了什么问题:

db.monitoraservicos.aggregate([
    {
        "$match": { "instancia": "bat1" }
    },
    {
        $group:
        {
            _id: '$instancia',
            uptime: { $max: "$uptime" },
            time: { $first: '$time' }
        }
    }, { $project: { uptime: 1, time: 1, instancia: '$_id', _id: 0 } }
])

或者这可能不需要$project阶段要好得多,它会在输出中留下一个附加字段_id:'',可以选择将其排除在$project

db.monitoraservicos.aggregate([
    {
        "$match": { "instancia": "bat1" }
    },
    {
        $group:
        {
            _id: '',
            uptime: { $max: "$uptime" },
            time: { $first: '$time' },
            instancia: { $first: '$instancia' }
        }
    }
])

如果您有不同的时间戳,那么您需要这样做:

db.monitoraservicos.aggregate([
    {
        "$match": { "instancia": "bat1" }

    },
    {
        "$group": {
            "_id": {
                "instancia": "$instancia",
                "uptime": { "$max": "$uptime" },
                "time": "$time"
            }
        }
    },
    {
        "$project": {
            "instancia": "$_id.instancia",
            "uptime": "$_id.uptime",
            "time": "$_id.time",
            "_id": 0
        }
    },
    { "$sort": { "uptime": -1 } }, { $limit: 1 }
])

实际上,对于与 匹配的所有记录,您的数据集似乎具有相同的时间{ "instancia": "bat1" },但是如果您在文档的时间字段中具有不同的日期,那么第一个查询将为您获取它在$group阶段找到的第一个文档的值,而不管该文档的正常运行时间是否是最大值与否(时间值也可以从 86 开始),但第二个查询应该可以正常工作,除非您在几个文档中有 221,同样,这些文档的时间不同 - 这种情况下它会从第一次匹配 221 中获取时间文档(总而言之,第一个查询最适合大多数情况)。

对此数据集进行尝试和测试:

/* 1 */
{
    "_id" : ObjectId("5d8ce9cf8efa15b6d2fc0179"),
    "instancia" : "bat1",
    "servico" : "eal_server",
    "status" : "UP",
    "diahora" : "221d 12h",
    "time" : ISODate("2019-09-26T19:36:37.000Z"),
    "uptime" : 21.0
}

/* 2 */
{
    "_id" : ObjectId("5d8ce9d08efa15b6d2fc017d"),
    "instancia" : "bat1",
    "servico" : "eps_server",
    "diahora" : "221d 12h",
    "status" : "UP",
    "time" : ISODate("2019-09-26T13:36:37.000Z"),
    "uptime" : 221.0
}

/* 3 */
{
    "_id" : ObjectId("5d8ce9d18efa15b6d2fc0181"),
    "instancia" : "bat1",
    "servico" : "fws_server.py",
    "diahora" : "86d 4h",
    "uptime" : 86.0,
    "status" : "UP",
    "time" : ISODate("2019-09-26T13:37:37.000Z")
}

/* 4 */
{
    "_id" : ObjectId("5d8ce9d18efa15b6d2fc0186"),
    "instancia" : "bat1",
    "servico" : "pra_assy_server",
    "time" : ISODate("2019-09-26T13:36:36.000Z"),
    "uptime" : 221.0,
    "diahora" : "221d 12h",
    "status" : "UP"
}

/* 5 */
{
    "_id" : ObjectId("5d8ce9d28efa15b6d2fc018c"),
    "instancia" : "bat1",
    "servico" : "pra_record_server",
    "status" : "UP",
    "time" : ISODate("2019-09-26T13:37:37.000Z"),
    "diahora" : "221d 12h",
    "uptime" : 221.0
}

/* 6 */
{
    "_id" : ObjectId("5d8ce9d38efa15b6d2fc0190"),
    "instancia" : "bat1",
    "servico" : "res_server",
    "status" : "UP",
    "diahora" : "221d 12h",
    "uptime" : 221.0,
    "time" : ISODate("2019-09-26T13:37:37.000Z")
}

/* 7 */
{
    "_id" : ObjectId("5d8ce9d38efa15b6d2fc0194"),
    "instancia" : "bat1",
    "servico" : "seq_file_server",
    "status" : "UP",
    "time" : ISODate("2019-09-26T13:37:37.000Z"),
    "diahora" : "221d 12h",
    "uptime" : 221.0
}

推荐阅读