У меня есть следующий образец данных:
{
_id: 1,
seniorityDate: '2001-01-01T00:00:00Z',
assigned: [
{
groupId: 11,
system: 'Dep',
effectiveDate: null
},
{
groupId: 12,
system: 'Team',
effectiveDate: null
},
...
]
}
и я хотел бы обновить объект effectiveDate на основе seniorityDate в массиве assigned, где только system:'Team':
db.collection.updateMany({},
[{
$set: {
'assigned.$[elem].effectiveDate': '$seniorityDate'
}
}], {
arrayFilters: [{
"elem.system": "Team"
}]
})
но я получил следующую ошибку:
arrayFilters не может быть указан для конвейерных обновлений.
Ожидаемый результат будет:
{
_id: 1,
seniorityDate: '2001-01-01T00:00:00Z',
assigned: [
{
groupId: 11,
system: 'Dep',
effectiveDate: null
},
{
groupId: 12,
system: 'Team',
effectiveDate: '2001-01-01T00:00:00Z'
},
...
]
}
Как я могу достичь этого?

Вы не можете использовать arrayFilters одновременно с конвейером агрегации. Пока вы обновляете значение из другого поля, поэтому вы можете достичь только с помощью конвейера агрегации.
$set - установить поле assigned.
1.1. $map — перебрать элемент в массиве assigned и вернуть новый массив.
1.1.1. $mergeObjects - объединить текущий повторный документ с документом из 1.1.1.1.
1.1.1.1. Документ с полем effectiveDate. С оператором $cond, если соответствует условию, используйте значение seniorityDate, в противном случае сохраните существующее значение.
db.collection.updateMany({},
[
{
$set: {
"assigned": {
$map: {
input: "$assigned",
in: {
$mergeObjects: [
"$$this",
{
effectiveDate: {
$cond: {
if: {
$eq: [
"$$this.system",
"Team"
]
},
then: "$seniorityDate",
else: "$$this.effectiveDate"
}
}
}
]
}
}
}
}
}
])
Благодаря предложению @rickhg12hs всегда ограничивайте документ для повышения производительности, поскольку вы знаете, какой документ/поле следует обновлять по условию.
Следовательно, ваш запрос на обновление с условием запроса будет выглядеть следующим образом:
db.collection.updateMany({
"assigned.system": "Team"
},
[
...
])
Демонстрация @ Mongo Playground
Да, вы правы, ограничьте количество документов для повышения производительности запросов. Спасибо за предложение. знак равно
Спасибо, @rickhg12hs за ваше действительное предложение.
Поскольку обновлять нужно только документы с
"assigned.system": "Team", вы можете добавить это как фильтр кupdateMany.