Как получить argmax / argmin из нескольких полей одновременно в mongodb?

#mongodb

#mongodb

Вопрос:

Вот пример данных, с которым я работаю.

 [
  {
    "uid": "111",
    "a": 1,
    "b": 3,
    "c": 1,
    
  },
  {
    "uid": "222",
    "a": 2,
    "b": 2,
    "c": 2
  },
  {
    "uid": "333",
    "a": 3,
    "b": 1,
    "c": 3
  }
]
 

Затем я хочу выполнить argmax работу с полями «a» и «b», а argmin также с полем «c» и вернуть "uid" результат.

Например:

Для «a» его максимальное значение равно 3, соответствующий «uid» равен «333», поэтому argmax должно быть «a» "uid" : "333" .

Вопрос в том, какой запрос должен быть выполнен, чтобы я мог получить результат, как показано ниже?

 [
  {
    "argmax_of_a": "333",
    "argmax_of_b": "111",
    "argmin_of_c": "111",
  }
]
 

Вот фрагмент кода, с которым я играю https://mongoplayground.net/p/gEDuHd-aCiZ

Я могу найти какой-то способ получить argmax/argmin одно конкретное поле, но я понятия не имею, как работать с несколькими полями одновременно.

Заранее спасибо!

Комментарии:

1. Предположим, что он всегда возвращает первый результат сопоставления.

Ответ №1:

попробуйте этот конвейер агрегации:

 db.collection.aggregate(
[
    {
        $group: {
            _id: null,
            a: { $push: { uid: '$uid', val: '$a' } },
            b: { $push: { uid: '$uid', val: '$b' } },
            c: { $push: { uid: '$uid', val: '$c' } }
        }
    },
    {
        $project: {
            _id: 0,
            max_of_a: { $arrayElemAt: ["$a", { $indexOfArray: ["$a.val", { $max: '$a.val' }] }] },
            max_of_b: { $arrayElemAt: ["$b", { $indexOfArray: ["$b.val", { $max: '$b.val' }] }] },
            max_of_c: { $arrayElemAt: ["$c", { $indexOfArray: ["$c.val", { $max: '$c.val' }] }] }
        }
    },
    {
        $project: {
            arg_max_of_a: '$max_of_a.uid',
            arg_max_of_b: '$max_of_b.uid',
            arg_max_of_c: '$max_of_c.uid'
        }
    }
])
 

Комментарии:

1. Потрясающее решение! Спасибо. Но я не уверен в производительности этого запроса? Например, сравнивать с первым сортом.

2. он должен нормально работать для нескольких тысяч документов. я сделаю это еще раз, когда у меня будет немного времени, чтобы придумать более эффективный способ.