Mongo返回两行而不是一行

时间:2019-09-26 18:51:08

标签: mongodb

我在mongodb中使用$max参数有问题。

我只想返回一个最大的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")
    }
  • 我也尝试将$max放在$project中,但没有用

谢谢

2 个答案:

答案 0 :(得分:2)

请尝试此操作,也请检查我的评论以了解您的查询出了什么问题:

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
}

答案 1 :(得分:1)

$max accumulator _id 内部不起作用,您需要在$max下直接写$group < / p>

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