【问题标题】:Mongo update multiple fields of an object which is inside an arrayMongo更新数组内对象的多个字段
【发布时间】: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,注意

标签: arrays mongodb mongoose mongodb-query


【解决方案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
}

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

【讨论】:

  • 所以,我可以多次使用位置运算符!谢谢!
猜你喜欢
  • 2016-05-10
  • 2021-02-25
  • 1970-01-01
  • 2023-04-07
  • 1970-01-01
  • 2022-11-01
  • 1970-01-01
  • 2018-10-15
  • 1970-01-01
相关资源
最近更新 更多