Найти элемент max внутри массива - PullRequest
0 голосов
/ 21 января 2019

REF: MongoDB Документ из массива со значением поля max

Ответы в Поиск наибольшего значения из подмассивов в документах и MongoDB найти по макс.значение в массиве документов предлагает использовать 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 голосов
/ 21 января 2019

Если вы хотите, чтобы все документы имели наибольшее значение, вы должны использовать фильтр. Таким образом, в основном, вместо того, чтобы использовать раскрутку, проект и т. Д., Просто используйте следующую стадию проекта

                $project: {
                    age: {
                        $filter: {
                            input: "$array",
                            as: "item",
                            cond: { $eq: ["$$item.age", { $max: "$array.age" }] }
                        }
                    }
                }
0 голосов
/ 21 января 2019

Вы можете использовать ниже aggregation

db.collection.aggregate([
  { "$project": {
    "max": {
      "$arrayElemAt": [
        "$array",
        {
          "$indexOfArray": [
            "$array.age",
            { "$max": "$array.age" }
          ]
        }
      ]
    }
  }}
])
0 голосов
/ 21 января 2019

вы можете попробовать это агрегирование с $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 } }
...