我正试图把这个
{
"fooList" : [
{
"bar" : {
"baz" : 100
}
},
{
"bar" : {
"baz" : 200
}
}
]
},
{
"fooList" : [
{
"bar" : {
"baz" : 300
}
},
{
"bar" : {
"baz" : 400
}
}
]
}
变成这样:
{
"fooList" : [
{
"baz" : 100,
"bar" : {
"baz" : 100
}
},
{
"baz" : 200,
"bar" : {
"baz" : 200
}
}
]
},
{
"fooList" : [
{
"baz" : 300,
"bar" : {
"baz" : 300
}
},
{
"baz" : 400,
"bar" : {
"baz" : 400
}
}
]
}
正如您所看到的,我实际上只是从bar
中复制了baz
及其值,但我的问题是它发生在数组中。
db.getCollection(<collection_name>).updateMany(
{},
{ $set: { 'fooList.$[element].baz' : '$fooList.$[element].bar.baz' } },
{ upsert: true ,
arrayFilters: [{'element.bar' : { $exists : true }}]
}
)
但这只会将字符串$fooList.$[element].bar.baz
设置为baz,如结果所示
[
{
"_id": ObjectId("5a934e000102030405000000"),
"fooList": [
{
"bar": {
"baz": 100
},
"baz": "$fooList.$[element].bar.baz"
}
]
}
]
谁能告诉我我可能做错了什么,或者这是否可能?谢谢
2条答案
按热度按时间1rhkuytd1#
您可以在mongoDB 4.2+的更新中使用聚合管道来完成此操作,如下所示:
解释道:
1.您$set $map数组文档,并根据嵌套元素“bar.baz”存在的条件进行合并,然后添加等于从bar. baz中获取的值的对象baz。
1.添加multi:true以用于所有匹配更新查询过滤器的文档,或者您可以使用updateMany()
playground
不幸的是,当您将更新与聚合管道一起使用时,arrayFilters是不可能的...
对于较早的mongodb版本,它看起来像这样:
x6h2sr282#
下面是一个变体,它演示了v4.4的“merge on-self”功能,该功能将
aggregate
转换为update
。当您希望处理所有文档时,这是一个有用的方法,因为它消除了update
所需的“无过滤器”({}
)和{multi:true}
位。