Find max element inside an array

女生的网名这么多〃 提交于 2019-12-12 12:34:08

问题


REF: MongoDB Document from array with field value max

Answers in Finding highest value from sub-arrays in documents and MongoDB find by max value in array of documents suggest to use sort + limit(1), however this is really slow. Surely there is a way to use the $max operator.

Suppose one gets a document like this in an aggregate match:

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

And you want to find the (entire, not just the one value) document where age is highest. How do you do that with the $max operator?

I tried

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

so I get

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

Then I tried matching age:

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

, but that gives me no results.

In other words what I need to get is the name and all other fields that belong to the oldest person in the array. And there are many thousands of persons, with lots of attributes, and on top of it all it runs on a raspberry pi. And I need to do this operation on a few dozen of such arrays. So with the sorting this takes about 40 seconds all in all. So I would really like to not use sort.


回答1:


can you try this aggregation with $reduce

db.t63.aggregate([
    {$addFields : {array : {$reduce : {
        input : "$array", 
        initialValue : {age : 0}, 
        in : {$cond: [{$gte : ["$$this.age", "$$value.age"]},"$$this", "$$value"]}}
    }}}
])

output

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



回答2:


If you want all the documents which have the highest value, you should use a filter. So basically, instead of using those unwind, project, etc, just use the below project stage

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



回答3:


You can use below aggregation

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


来源:https://stackoverflow.com/questions/54292286/find-max-element-inside-an-array

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!