【问题标题】:MongoDB - Get id of the maximum value in a group by queryMongoDB - 通过查询获取组中最大值的 id
【发布时间】:2015-10-07 23:13:23
【问题描述】:

我有一个文档如下所示的集合。我想获取“_id”或按“名称”分组的每个组中具有最大修订版的文档的整个文档。

{
    "_id" : ObjectId("55aa088a58f2a8f2bd2a3793"),
    "name" : "abc",
    "revision" : 1
}

{
    "_id" : ObjectId("55aa088a58f2a8f2bd2a3794"),
    "name" : "abc",
    "revision" : 2
}

{
    "_id" : ObjectId("55aa088a58f2a8f2bd2a3795"),
    "name" : "def",
    "revision" : 1
}

{
    "_id" : ObjectId("55aa088a58f2a8f2bd2a3796"),
    "name" : "def",
    "revision" : 2
}

在这种情况下,我只想选择第 2 个和第 4 个文档。我尝试了各种方法,包括聚合框架,但不能纯粹在 MongoDB 查询中做到这一点。

有解决办法吗?

谢谢。

【问题讨论】:

    标签: mongodb


    【解决方案1】:

    尝试以下聚合管道,首先按修订字段降序对文档进行排序,然后按名称字段$group,使用@添加另一个获取完整文档的字段$$ROOT 系统变量表达式上的 987654322@ 运算符:

    db.collection.aggregate([
        {
            "$sort": {
                "revision": -1
            }
        },
        {
            "$group": {
                "_id": "$name",
                "max_revision": {
                    "$max": "$revision"
                },
                "doc": {
                    "$first": "$$ROOT"
                }
            }
        }
    ])
    

    输出

    /* 0 */
    {
        "result" : [ 
            {
                "_id" : "def",
                "max_revision" : 2,
                "doc" : {
                    "_id" : ObjectId("55aa088a58f2a8f2bd2a3796"),
                    "name" : "def",
                    "revision" : 2
                }
            }, 
            {
                "_id" : "abc",
                "max_revision" : 2,
                "doc" : {
                    "_id" : ObjectId("55aa088a58f2a8f2bd2a3794"),
                    "name" : "abc",
                    "revision" : 2
                }
            }
        ],
        "ok" : 1
    }
    

    【讨论】:

    • 谢谢。学到了很多新东西,比如 $$ROOT sys 变量。
    • 有没有更优雅的方法来查找产生最大值的文档,而不需要对整个集合进行排序?与找到最大值相比,排序非常昂贵。
    【解决方案2】:

    您应该使用Mongo aggregation 来获得预期的输出。

    查询将如下所示:

    db.collection.aggregate({
        $group: {
        _id: "$name",
        "revision": {
            $max: "$revision"
        }
        }
    }, {
        $project: {
        "name": "$_id",
        "revision": 1,
        "_id": 0
        }
    })
    

    编辑

    您可以使用如下查询-

    db.collection.aggregate({
        $sort: {
        revision: -1
        }
    }, {
        $group: {
        _id: "$name",
        "revision": {
            "$max": "$revision"
        },
        "original": {
            $first: "$$ROOT"
        }
        }
    }, {
        $project: {
        "name": "$_id",
        "revision": 1,
        "_id": "$original._id"
        }
    })
    

    【讨论】:

    • 感谢您的回答。这正是我之前尝试过的。问题是这没有给出文档ID。我的要求是选择那些修订版本最高的文档并做一些进一步的操作。或者,如果我可以获得文档的 id,至少可以在第二次查询中使用它来获取这些文档。
    • @Sujee 您可以通过发布您在问题中尝试过的内容来避免这种情况。建议这样做。请阅读指南/帮助或参观。
    • 感谢更新的答案。是的。这是我一直在寻找的。​​span>
    • @Elyasin 感谢您的来信。我会遵循建议。
    猜你喜欢
    • 2023-03-09
    • 2019-02-12
    • 2018-11-26
    • 1970-01-01
    • 2019-02-18
    • 2018-03-01
    • 2020-01-03
    • 1970-01-01
    • 2010-10-19
    相关资源
    最近更新 更多