获取所有行,分组和最大值

时间:2016-07-27 17:27:19

标签: mongodb mongodb-query aggregation-framework

例如,我有这些数据:

{project: "1": platform: "1", number: 10}
{project: "1": platform: "1", number: 10}
{project: "1": platform: "1", number: 40}
{project: "1": platform: "1", number: 40}

{project: "1": platform: "2", number: 20}
{project: "1": platform: "2", number: 20}
{project: "1": platform: "2", number: 30}
{project: "1": platform: "2", number: 30}

{project: "2": platform: "2", number: 50}
{project: "2": platform: "2", number: 50}
{project: "2": platform: "2", number: 60}
{project: "2": platform: "2", number: 60}

我想获得按项目和平台分组的行,并获取具有最大数量的所有行。上述数据的结果应为:

{project: "1": platform: "1", number: 40}
{project: "1": platform: "1", number: 40}
{project: "1": platform: "2", number: 30}
{project: "1": platform: "2", number: 30}
{project: "2": platform: "2", number: 60}
{project: "2": platform: "2", number: 60}

我尝试使用$ max在$ group._id中使用项目和平台进行聚合,但查询只返回一行最大数量。如何通过mongodb制作?

2 个答案:

答案 0 :(得分:1)

以下是基于$filter运算符的解决方案:

db.projects.aggregate([{$group: {_id: {project: "$project", platform: "$platform"}, numbers: {$push: "$number"}, max: {$max: "$number"}}},
                       {$project: {_id: 0,
                                   project: "$_id.project",
                                   platform: "$_id.platform",
                                   number: {$filter: {
                                                      input: "$numbers",
                                                      as: "number",
                                                      cond: {$eq: ["$$number", "$max"]}
                                                     }
                                           }
                                  }
                       },
                       {$unwind: "$number"}]);

如果原始文档中有更多字段,您可以尝试:

As far as I understand you need something like this db.projects.aggregate([{$group: {_id: {project: "$project", platform: "$platform"}, documents: {$push: "$$ROOT"}, max: {$max: "$number"}}},
                       {$project: {_id: 0,
                                   document: {$filter: {
                                                      input: "$documents",
                                                      as: "document",
                                                      cond: {$eq: ["$$document.number", "$max"]}
                                                     }
                                           }
                                  }
                       },
                       {$unwind: "$document"},
                       {$project: {_id: "$document._id", number: "$document.number", ANOTHER_FIELD: "$ANOTHER_FIELD"}}]);

答案 1 :(得分:0)

在进入聚合查询之前检查以下链接以供参考:

1>的 Encode method source

2 - ;的 Mongo $eq

3>的 $setDifference

4>的 $sond

首先我们按platformproject进行分组,然后在聚合中使用number查找最大group,并在组中使用$$ROOT添加所有数据。然后使用$map迭代所有数据并检查匹配的最大数量,并仅获取那些最大匹配数据。

db.collection.aggregate([{
    "$group": {
        "_id": {
            "project": "$project",
            "paltform": "$platform"
        },
        "max": {
            "$max": "$number"
        },
        "mainData": {
            "$push": "$$ROOT"
        }
    }
}, {
    "$project": {
        "findMax": {
            "$setDifference": [{
                    "$map": {
                        "input": "$mainData",
                        "as": "el",
                        "in": {
                            "$cond": {
                                "if": {
                                    "$eq": ["$$el.number", "$max"]
                                },
                                "then": "$$el",
                                "else": false
                            }
                        }
                    }
                },
                [false]
            ]
        },
        "_id": 0
    }
}, {
    "$unwind": "$findMax"
}, {
    "$project": {
        "_id": "$findMax._id",
        "project": "$findMax.project",
        "platform": "$findMax.platform",
        "number": "$findMax.number"
    }
}])

如果您删除了上一个uniwndproject,也可以获得结果。