У меня есть образец документа с вложенными массивами, как показано ниже. {
"locations" : [
{
"appointments" : [
{
"apptId" : "3456",
"status" : ""
},
{
"apptId" : "12345",
"status" : ""
}
]
},
{
"appointments" : [
{
"apptId" : "12345",
"status" : ""
},
{
"apptId" : "3456",
"status" : ""
}
]
}
]
}
Я хотел бы обновить только тот поддокумент во вложенном массиве, который удовлетворяет моим критериям.
Я попытался использовать приведенный ниже запрос, но не могу обновить конкретный документ, который может находиться в любом индексе во вложенном массиве. Это дает мне нежелательные результаты.
Query query = new Query(); query.addCriteria(Criteria.where("locations.appointments.apptId").is(apptId));
Update update = new Update();
update.set("locations.$[].appointments.$.status", "cancelled");
WriteResult wrote = mongoTemplate.updateMulti(query, update, Schema.class, collectionName);
Мой ожидаемый результат - обновить статус 2-й встречи в первом месте и 1-й встречи во 2-м месте (т.е. критерии, соответствующие apptId = 12345) до «отменено». Я пытался использовать update.set("locations.$[].appointments.$.status", "cancelled");
и update.set("locations.$[].appointments.$[].status", "cancelled");
, это просто не дало желаемого результата.
Пожалуйста, помогите мне с этим. Моя версия MongoDB — 3.6.10. Спасибо!
arrayFilters
и$[<identifier>]
с позиционной фильтрацией, поскольку позиционное all$[]
просто обновляет ВСЕ элементы массива, а не только те критерии соответствия. Вместо этого у вас есть что-то вроде"locations.$[].appointments.$[elem].status", "cancelled"
в качестве аргументов для$set
и{ "arrayFilters": [{ "elem.apptId": "3456" }] }
или.filterArray(Criteria.where("elem.apptId").eq("3456"))
, которые теперь объединены в spring mongo. Обратите внимание, что если ваша версия весеннего монго еще не поддерживает это, вы всегда можете получить коллекцию из необработанного драйвера. - person Neil Lunn   schedule 07.04.2019$[<identifier>]
и позиционный al$[]
обновляют ВСЕ совпадения (или все). Если вы ожидали, что обновится только одно из совпадающих значений, вы должны включить уникальный идентификатор в"locations"
и сделать что-то вроде$set: { "location.$[outer].appointments.$[inner].status": "cancelled" }
и{ "arrayFilters": [{ "outer._id": "uniqueId" },{ "inner.apptId": "3456" }] }
илиList
изCriteria
в зависимости от ситуации. Первый связанный дубликат объясняет, почему позиционный$
ненадежен даже для one с вложенным массивом. - person Neil Lunn   schedule 07.04.2019