在数组中查找最大元素

时间:2019-01-21 14:41:10

标签: mongodb mongodb-query aggregation-framework

REF:MongoDB Document from array with field value max

Finding highest value from sub-arrays in documentsMongoDB find by max value in array of documents中的答案建议使用sort + limit(1),但这确实很慢。当然可以使用$ max运算符。

假设某人通过汇总匹配获得了这样的文档:

{
  _id: "notImportant",
  array: [
    {
      name: "Peter",
      age: 17
    },
    {
      name: "Carl",
      age: 21
    },
    {
      name: "Ben",
      age: 15
    }
  ]
}

您想找到年龄最高的(整个,而不仅仅是一个值)文档。 您如何使用$ max运算符来做到这一点?

我尝试过

unwind {"$array"}
project {"_id": 0, "name": "$array.name", "age": "$array.age"}

所以我得到

{
  _id: null,
  name: "Peter",
  age: 17
}
{
  _id: null,
  name: "Carl",
  age: 21
}
{
  _id: null,
  name: "Ben",
  age: 15
}

然后我尝试匹配年龄:

age: {$eq: {$max: "$age"}}

,但是没有任何结果。

换句话说,我需要得到的是名称和所有其他属于数组中最早的人的字段。有成千上万的人,具有许多属性,最重要的是,它全部在树莓派上运行。我需要在几十个这样的阵列上执行此操作。因此,排序总共需要40秒钟左右。所以我真的不想使用排序。

3 个答案:

答案 0 :(得分:2)

如果要使所有文档的价值最高,则应使用过滤器。 因此,基本上,不要使用那些展开,项目等方法,而要使用下面的项目阶段

                $project: {
                    age: {
                        $filter: {
                            input: "$array",
                            as: "item",
                            cond: { $eq: ["$$item.age", { $max: "$array.age" }] }
                        }
                    }
                }

答案 1 :(得分:1)

您可以尝试使用$reduce

进行此聚合吗?
db.t63.aggregate([
    {$addFields : {array : {$reduce : {
        input : "$array", 
        initialValue : {age : 0}, 
        in : {$cond: [{$gte : ["$$this.age", "$$value.age"]},"$$this", "$$value"]}}
    }}}
])

输出

{ "_id" : "notImportant", "array" : { "name" : "Carl", "age" : 21 } }

答案 2 :(得分:1)

您可以在aggregation下使用

db.collection.aggregate([
  { "$project": {
    "max": {
      "$arrayElemAt": [
        "$array",
        {
          "$indexOfArray": [
            "$array.age",
            { "$max": "$array.age" }
          ]
        }
      ]
    }
  }}
])