Вот очень простой пример данных ниже:
[
{
"data": [
{
"uid": "0",
"value": 0,
},
{
"uid": "1",
"value": 1,
},
{
"uid": "2",
"value": 2,
}
]
}
]
Затем я хочу найти соответствующее uid
максимума value
. В моем случае результат должен быть "2"
.
Вот запрос, с которым я играю:
db.collection.aggregate([
{
"$project": {
"_id": 0,
"value_argmax": {
"$arrayElemAt": [
"$data.uid",
{
"$indexOfArray": [
"$data.value",
{
"$max": "$data.value"
}
]
}
]
}
}
}
])
Код работает для моего случая. Однако при наличии некоторых отсутствующих полей код запроса может завершиться ошибкой. Например, если у меня есть пример данных, который выглядит следующим образом:
[
{
"data": [
{
"uid": "0",
// "value": 0, // missing field
},
{
"uid": "1",
"value": 1,
},
{
"uid": "2",
"value": 2,
}
]
}
]
Результатом моего запроса будет «1» вместо «2» (в моем случае я просто хочу опустить отсутствующее поле).
Итак, что мне делать, чтобы исправить мой запрос? Вот простой тестовый пример: https://mongoplayground.net/p/8qiFRB8EsSE
Заранее спасибо!
В этом случае просто верните соответствующее uid
существующего максимального значения first
.
Попробуй это:
db.collection.aggregate([
{
$set: {
data: {
$filter: {
input: "$data",
cond: { $eq: [{ $max: "$data.value" }, "$$this.value"] }
}
}
}
},
{ $set: { value_argmax: { $first: "$data.uid" } } },
{ $unset: "data" }
])
Очень хорошее решение, спасибо! Только один вопрос, какая разница между set
и project
здесь? Я нахожу, что оба работают нормально.
$project
показывает указанные поля и удаляет все остальные поля. $set
(или псевдоним $addFields
) добавляет или обновляет поля, не касаясь других. Итак, в вашем примере не имеет значения, какой из них вы используете.
Для людей, которые используют более раннюю версию MongoDB, вы можете использовать arrayElemAt
с индексом 0 вместо first
. В противном случае это может вызвать ошибку запроса.
Что вы ожидаете, когда максимальное значение существует более одного раза?