Обновить поле в массиве точного элемента в MongoDB
У меня есть документ, структурированный следующим образом:
{
_id:"43434",
heroes : [
{ nickname : "test", items : ["", "", ""] },
{ nickname : "test2", items : ["", "", ""] },
]
}
Могу ли я $set
второй элемент массива items
встроенного объекта в массиве heros
с nickname
"test"
?
Результат:
{
_id:"43434",
heroes : [
{ nickname : "test", items : ["", "new_value", ""] }, // modified here
{ nickname : "test2", items : ["", "", ""] },
]
}
Ответы
Ответ 1
Вам нужно использовать 2 понятия: оператор позиционирования mongodb и просто использовать числовой индекс для записи, которую вы хотите обновить.
Оператор positional позволяет использовать такое условие:
{"heros.nickname": "test"}
а затем ссылайтесь на найденный массив так:
{"heros.$ // <- the dollar represents the first matching array key index
Как вы хотите обновить запись 2-го массива в "элементах", а ключи массива индексируются 0 - что ключ 1.
Итак:
> db.denis.insert({_id:"43434", heros : [{ nickname : "test", items : ["", "", ""] }, { nickname : "test2", items : ["", "", ""] }]});
> db.denis.update(
{"heros.nickname": "test"},
{$set: {
"heros.$.items.1": "new_value"
}}
)
> db.denis.find()
{
"_id" : "43434",
"heros" : [
{"nickname" : "test", "items" : ["", "new_value", "" ]},
{"nickname" : "test2", "items" : ["", "", "" ]}
]
}
Ответ 2
db.collection.update(
{
heroes:{$elemMatch:{ "nickname" : "test"}}},
{
$push: {
'heroes.$.items': {
$each: ["new_value" ],
$position: 1
}
}
}
)
Ответ 3
Это решение хорошо работает. Просто хочу добавить одну точку. Вот структура. Мне нужно найти OrderItemId 'yyy' и обновить. Если поле запроса в условии является массивом, как показано ниже, "OrderItems.OrderItemId" является массивом. Вы не можете использовать "OrderItems.OrderItemId [0]" как операцию в запросе. Вместо этого вам нужно использовать "OrderItems.OrderItemId" для сравнения. В противном случае он не может совпадать с одним.
{
_id: 'orderid',
OrderItems: [
{
OrderItemId: ['xxxx'],
... },
{
OrderItemId: ['yyyy'],
...},
]
}
result = await collection.updateOne(
{ _id: orderId, "OrderItems.OrderItemId": [orderItemId] },
{ $set: { "OrderItems.$.imgUrl": imgUrl[0], "OrderItems.$.category": category } },
{ upsert: false },
)
console.log(' (result.modifiedCount) ', result.modifiedCount)
console.log(' (result.matchedCount) ', result.matchedCount)