Mongo汇总,分组,最大并采用具有最大值的整个行

时间:2019-03-11 12:06:54

标签: mongodb

最新编辑:我设法在$ project中使用$ filter解决了该问题。 $ filter将返回一个具有单个对象的Array(如果每个instanceId-entity组合具有单个maxValue),则必须对其进行$ unwind-ed处理。代码:

 {$group: {
             _id: {instanceId: "$instanceId", entity: "$entity"},
             maxValue: {$max: "$value"},
             originalDocs: {"$push": "$$ROOT"}
          }
 },
 {$project: {
            "originalDoc": { "$filter": {
                                    "input": "$originalDocs",
                                    "as": "doc",
                                    "cond": { 
                                           "$eq": [ "$maxValue", "$$doc.value" ]  
                                            }
                                   }
                            },
            }
  },
  { $unwind : "$originalDoc" },
  { $project: {
                "instanceId": "$originalDoc.instanceId",
                "entity": "$originalDoc.entity",
                "value": "$originalDoc.value",
                "details": "$originalDoc.details",
             }    
  }

我有此数据:

id: 1, instanceId: 1, entity: a, value: 1, details: "some details 1" 
id: 2, instanceId: 1, entity: a, value: 3, details: "some details 2"
id: 3, instanceId: 1, entity: a, value: 5, details: "some details 3" 
id: 4 ,instanceId: 1, entity: a, value: 10, details: "some details 4" 

id: 5, instanceId: 1, entity: b, value: 1, details: "some details 5" 
id: 6, instanceId: 1, entity: b, value: 2, details: "some details 6" 
id: 7, instanceId: 1, entity: b, value: 5, details: "some details 7" 

id: 8, instanceId: 2, entity: a, value: 3, details: "some details 8" 
id: 9, instanceId: 2, entity: a, value: 4, details: "some details 9" 
id:10, instanceId: 2, entity: a, value: 6, details: "some details 10" 

我对[ instanceId 实体]进行了分组,并采用MAX

 $group:{
           _id:{instanceId: "$instanceId", entityName: "$entityName"},
           maxValue: {$max: "$value"},
        }

并得到了很好的结果:

id: 4 ,instanceId: 1, entity: a, maxValue: 10   
id: 7, instanceId: 1, entity: b, maxValue: 5
id:10, instanceId: 2, entity: a, maxValue: 6

但是我也想要细节。这就是我想要的:

id: 4 ,instanceId: 1, entity: a, maxValue: 10, details: "some details 4"    
id: 7, instanceId: 1, entity: b, maxValue: 5, details: "some details 7" 
id:10, instanceId: 2, entity: a, maxValue: 6, details: "some details 10"

如果我使用“ $ push”:“ $$ ROOT” ,则将为每个组合分组的所有我的文档都将被推送,并将获得如下信息:

id: 4 ,instanceId: 1, entity: a, maxValue: 10, originalDocument: Array[4]    
id: 7, instanceId: 1, entity: b, maxValue: 5, originalDocument: Array[3] 
id:10, instanceId: 2, entity: a, maxValue: 6, originalDocument: Array[3]

我只想要与最大值对应的原始文档

1 个答案:

答案 0 :(得分:1)

尝试此汇总查询,它将解决您的问题。

        [{
          $group: {
            _id: {
              instanceId: "$instanceId",
              entity: "$entity"
            },
            maxValue: {
              $max: "$value"
            },
            details: {
              $push: '$$ROOT'
            }
          }
        }, {
          "$project": {
            _id: 0,
            proj_details: {
              "$setDifference": [{
                  "$map": {
                    "input": "$details",
                    "as": "mapped",
                    "in": {
                      "$cond": [{
                          "$eq": ["$maxValue", "$$mapped.value"]
                        },
                        "$$mapped",
                        false
                      ]
                    }
                  }
                },
                [false]
              ]
            }

          }
        }, {
          $unwind: '$proj_details'
        }, {
          $project: {
            "id": '$proj_details.id',
            "instanceId": '$proj_details.instanceId',
            "entity": "$proj_details.entity",
            "value": '$proj_details.value',
            "details": "$proj_details.details"
          }
        }]