#mongodb #aggregation-framework
Вопрос:
У меня есть коллекция MongoDB со структурой документа, аналогичной:
{
"_id" : "xxx",
"inner : {
"foo" : 1,
"bar" : 2
}
}
Версия базы данных 4.2.6
и конвейер агрегирования, предпоследний этап $project
которого связан с итоговым документом, соответствующим чему-то подобному этому:
{
"_id" : "xxx",
"inner : {
"baz" : 3
}
}
Затем следует заключительный этап для объединения в коллекцию:
{
"$merge" : {
into: "myCollection",
on: "_id",
whenMatched: "merge",
whenNotMatched: "discard"
}
}
Однако в результате существующие inner
поля документа переопределяются $merge
результатами. Значение:
Ожидаемые результаты:
{
"_id" : "xxx",
"inner : {
"foo" : 1,
"bar" : 2,
"baz" : 3
}
}
Фактические результаты:
{
"_id" : "xxx",
"inner : {
"baz" : 3
}
}
Как я могу преодолеть это?
Ответ №1:
Опция «объединить» объединяет корневой документ, поэтому inner
поле заменяется в вашем запросе.
попробуйте заменить слияние этим слиянием, использующим конвейер.
Я еще не тестировал его, но думаю, что все будет в порядке.
$$new
переменная определяется монго для ссылки на документ, поступающий из конвейера.
{
"$merge" : {
into: "myCollection",
on: "_id",
whenMatched:
[{"$project":
{"_id": "$_id",
"inner": {"$mergeObjects": ["$inner","$new.inner"]}}}],
whenNotMatched: "discard"
}
}
Ответ №2:
Принятый ответ был хорошей зацепкой, хотя $project
трубопровод привел к тому, что все поля, кроме _id
и inner
, были переопределены. Конечно, это не то, чего я хотел.
Что должно было быть очевидным выбором, так это просто использовать $addFields
вместо этого:
whenMatched: [
{"$addFields" :
{"inner.baz": "$new.baz"}
}
]