Из $ (позиционный оператор) docs:
позиционный оператор $ действует как заполнитель для первого элемента, который соответствует документу запроса, и
Позиционный оператор всегда соответствует первому документу в массиве, поэтому я предполагаю, что вы пытались выполнить сортировку по убыванию. Однако, хотя вы могли подумать, что этот подход может работать, он не будет работать, поскольку sort является оператором курсора, что означает, что он влияет только на сопоставление документа. Фактически невозможно отсортировать вложенный массив в Mon go до грядущей версии 4.4, где планируется ввести пользовательские функции.
Итак, что вы можете сделать? Если вы используете Mon go версии 4.2+, они представили конвейерные обновления , что дает нам больше возможностей, позволяя нам использовать выражения агрегации в обновлении, вот пример того, что с ним можно сделать:
db.test.updateOne(
{
"_id": new ObjectId(_id),
},
[
{
$set: {
filtered: {
$filter: {
input: "$manualChanges",
as: "change",
cond: {$ne: ["$$change.discarded", true]}
}
}
}
},
{
$set: {
last_id: {
$max: "$filtered.id",
}
}
},
{
$set: {
manualChanges: {
$map: {
input: "$manualChanges",
as: "change",
in: {
$mergeObjects: [
"$$change",
{
discarded: {$cond: [{$eq: ["$$change.id", "$last_id"]}, true, "$$change.discarded"]}
}
]
}
}
}
}
},
{
$unset: ["last_id", "filtered"]
}
])
Если вы используете более низкую версию Mon go, вам придется разделить это на 2 запроса, сначала найдите дополнительный документ id
и только потом вы сможете его обновить.