Mongo更新数组内对象的多个字段

Posted

技术标签:

【中文标题】Mongo更新数组内对象的多个字段【英文标题】:Mongo update multiple fields of an object which is inside an array 【发布时间】:2020-05-03 19:22:33 【问题描述】:

使用 Mongo findOneAndUpdate,我试图从对象数组中更新对象中的一些字段。

我的对象:

mainObject:
    _id: '123',
    array:[
        title:'title' , name:'name', keep:'keep',        
        title:'title', keep:'keep',
    ]

我想为数组中的第一个对象更改titlename,并保持keep 字段不变。 这是我使用Positional Operator 最接近的方法:

// here i set dynamic arguments for query update
// sometimes i need to update only one field, sometime i need to update more fields
// also, is there a better way to do this?

let title
let name

 if (args.title) 
      title =  title: args.title ;
    
 if (args.name) 
      name=  name: args.name;
    


db.Test.findOneAndUpdate(
         _id: args.id, 'mainObject.array.title': args.title,
        
          $set: 
            'mainObject.array.$[]': 
              ...title,
              ...name
              
          
      
 )

这个问题是它替换了整个对象,结果是:

mainObject:
    array:[
        title:'changed' , name:'changed',     //without keep...    :(
        title:'title', keep:'keep',
    ]

我应该为此使用聚合框架吗?

【问题讨论】:

聚合查询不能回写到同一个集合,它们的主要目的是查询而不是更新回,尽管有两个阶段$out -- 如果集合存在,将覆盖集合或创建一个新的 & $merge - 将写入新集合或创建新集合(这两个不是我们正在查看的),所以它必须是一个正常的更新过程。 @srinivasy,注意 【参考方案1】:

必须是这样的:

db.test.findOneAndUpdate('mainObject.array.title': 'title',
$set : 'mainObject.array.$.title':'changed','mainObject.array.$.name': 'changed')

根据您的查询,$ 将更新数组中与过滤器查询匹配的第一个找到的元素,如果您在 array 数组中有多个元素/对象,那么您可以使用 $[] 更新所有这些元素/对象,让我们看看您的查询:

'mainObject.array.$[]': 
              ...title,
              ...name
              

上述查询的主要问题是它将更新array数组中与过滤器匹配的所有对象:


    ...title,
    ...name

所以,它是一种替换整个对象。而是使用 . 表示法来更新特定值。

【讨论】:

所以,我可以多次使用位置运算符!谢谢!

以上是关于Mongo更新数组内对象的多个字段的主要内容,如果未能解决你的问题,请参考以下文章

在 Mongo 集合中更新数组中的一条记录

猫鼬:更新字段,将对象推送到数组中[重复]

想要在 Mongo 中更新数组对象值的数组

Mongo 文档中的更新数组不起作用

Mongo 查询(可视化工具)

Mongo - 更新文档时使用另一个字段的结果更新一个字段