#mongodb #mongodb-query
#mongodb #mongodb-запрос
Вопрос:
Мне нужно добавить элементы к определенному подобъекту в моей коллекции. Возможно ли это сделать, используя только метод обновления, учитывая, что массив может не существовать в некоторых объектах?
Вот пример структуры:
[
{
"key": 1,
"someValue": "abc",
"installments": [
{
"number": 1,
"payments": [
{
"paymentNumber": 1,
"value": 29
},
{
"paymentNumber": 2,
"value": 22
}
]
}
]
},
{
"key": 2,
"someValue": "xyz",
"installments": [
{
"number": 1,
"payments": [
{
"paymentNumber": 3,
"value": 10
},
{
"paymentNumber": 4,
"value": 1
},
{
"paymentNumber": 5,
"value": 5
}
]
}
]
}
]
И вот синтаксис, который я использую:
db.collection.update({
"installments.payments.paymentNumber": 4
},
{
"$push": {
"installments.payments": [
{
"receipts": [
{
"receiptNumber": 1
}
]
}
]
}
})
Это вызывает эту ошибку:
fail to run update: multiple write errors: [{write errors: [{Cannot create field 'payments' in element {installments: [ { number: 1.0, payments: [ { paymentNumber: 3.0, value: 10.0 }, { paymentNumber: 4.0, value: 1.0 }, { paymentNumber: 5.0, value: 5.0 } ] } ]}}]}, {<nil>}]
Возможно ли это?
Вот ссылка на игровую площадку Mongo
И вот ожидаемый результат:
[
{
"key": 1,
"someValue": "abc",
"installments": [
{
"number": 1,
"payments": [
{
"paymentNumber": 1,
"value": 29
},
{
"paymentNumber": 2,
"value": 22
}
]
}
]
},
{
"key": 2,
"someValue": "xyz",
"installments": [
{
"number": 1,
"payments": [
{
"paymentNumber": 3,
"value": 10
},
{
"paymentNumber": 4,
"value": 1,
"receipts": [{
"receiptNumber": 1
}]
},
{
"paymentNumber": 5,
"value": 5
}
]
}
]
}
]
Комментарии:
1. Можете ли вы опубликовать ожидаемый результат?
2. Конечно. Просто добавил его. Спасибо
Ответ №1:
Для обновления вложенных массивов отфильтрованный позиционный оператор $[идентификатор] идентифицирует элементы массива, которые соответствуют arrayFilters
условиям для операции обновления.
Попробуйте выполнить следующий запрос к $push во вложенном массиве:
db.collection.update({
"installments.payments.paymentNumber": 4,
},
{
"$push": {
"installments.$.payments.$[payments].receipts": {
"receiptNumber": 1
}
}
},
{
"arrayFilters": [
{
"payments.paymentNumber": 4
}
],
multi: true
})
Комментарии:
1. Это неправильно. Он должен добавить квитанции к элементу платежей с номером платежа, равным 4.
2. @JulianoNunesSilvaOliveira Я обновил ответ. Пожалуйста, проверьте
3. Если вы хотите обновить несколько документов, обязательно добавьте
multi:true
. Смотрите обновленный запрос4. Я не понял, почему это обновление нескольких документов, но ваш код действительно работал для того, что мне нужно. Я проверю план выполнения, чтобы узнать, быстрее ли это, чем запрашивать элемент и после этого добавлять новый элемент.