MongoDB:如何更新数组中的单个子元素,由数组中的索引引用?

Abe*_*Abe 64 arrays mongodb

我正在尝试更新mongodb文档中数组中包含的单个子元素.我想使用其数组索引引用该字段(数组中的元素没有任何我可以保证将是唯一标识符的字段).看起来这应该很容易,但我无法弄清楚语法.

这是我想在伪json中做的事情.

之前:

{
  _id : ...,
  other_stuff ... ,
  my_array : [
    { ... old content A ... },
    { ... old content B ... },
    { ... old content C ... }
  ]
}
Run Code Online (Sandbox Code Playgroud)

后:

{
  _id : ...,
  other_stuff ... ,
  my_array : [
    { ... old content A ... },
    { ... NEW content B ... },
    { ... old content C ... }
  ]
}
Run Code Online (Sandbox Code Playgroud)

好像查询应该是这样的:

//pseudocode
db.my_collection.update(
  {_id: ObjectId(document_id), my_array.1 : 1 },
  {my_array.$.content: NEW content B }
)
Run Code Online (Sandbox Code Playgroud)

但这不起作用.我花了太长时间搜索mongodb文档,并尝试不同的语法变体(例如使用$slice等).我找不到任何关于如何在MongoDB中完成此类更新的明确解释.

Abe*_*Abe 70

正如所料,一旦您知道如何,查询就很容易.这是python中的语法:

db["my_collection"].update(
    { "_id": ObjectId(document_id) },
    { "$set": { 'documents.'+str(doc_index)+'.content' : new_content_B}}
)
Run Code Online (Sandbox Code Playgroud)

  • 这绝对是一个过时的答案。 (7认同)
  • 这记录在哪里? (6认同)
  • 这最终会创建一个同名的对象,而不是更新数组 (4认同)

tom*_*kas 36

Mongo Shell中索引(例如1)引用的数组元素的更新也可以通过直接指示索引值来完成:

db.my_collection.update(
    {_id : "document_id"},
    {$set : {"my_array.1.content" : "New content B"}}
)
Run Code Online (Sandbox Code Playgroud)

  • 如果我们不知道索引怎么办? (18认同)

小智 21

在mongo风格中,使用'$'位置运算符.有关详细信息,请查看此链接.

db.my_collection.update(
  {_id: ObjectId(document_id), my_array.1 : 1 },
  { $set: { "my_array.$.content" : "NEW content B" } }
)
Run Code Online (Sandbox Code Playgroud)


iam*_*der 13

当需要更新数组元素而不知道它的实际索引但具有元素唯一标识符时:

// Modify a comment in a bucket
db.POST_COMMENT.update(
    {
        "_id": ObjectId("5ec424a1ed1af85a50855964"),
        "bucket.commentId": "5eaf258bb80a1f03cd97a3ad_lepf4f"
    },
    {
        $set: {
            "bucket.$.text": "Comment text changed",
            "bucket.$.createdDate": ISODate("2015-12-11T14:12:00.000+0000")
        }
    }
)
Run Code Online (Sandbox Code Playgroud)

"bucket.commentId"是数组元素的唯一标识符。


小智 10

当需要更新数组元素而不知道它是实际索引但具有元素的唯一标识符时

db.getCollection('profiles').update(
  {
    'userId':'4360a380-1540-45d9-b902-200f2d346263',
    'skills.name':'css'
  },
  {
      $set: {'skills.$.proficiencyLevel': 5}
  }, 
  {
      multi: true
  }
)
Run Code Online (Sandbox Code Playgroud)


小智 7

在 Javascript 中使用反引号的一种巧妙方法是:

 const index = 1;

 ...  {   $set: { [`myArray.${index}.value`]: "new content"}  },  ...
Run Code Online (Sandbox Code Playgroud)


小智 6

db.my_collection.update(
  {_id: ObjectId(document_id), my_array : { ... old content A ... } },
  { $set: { "my_array.$.content" : "NEW content B" } }
)
Run Code Online (Sandbox Code Playgroud)


Adw*_*ari 6

如果您想更新以下文档中 _id = 60c4918d74c30165ba585c14 的推荐的作者姓名:

"business": {
    "ownerId": "60a5ebad7432d91b853c0277",
    "testimonials": [
        {
            "_id": "60c4912877dd5664f2201b08",
            "authorName": "user1",
            "authorBio": "User from 10 years",
            "image": "user1/img1",
            "review": "asdfiuahsdfpoiuashdpfoaspdlfkjn;alsfpuoh"
        },
        {
            "_id": "60c4918d74c30165ba585c14",
            "authorName": "user2",
            "authorBio": "User from 3 years",
            "image": "user/img1",
            "review": "asdpfuahsfljnsadfoihsf."
        }
    ],
    "createdAt": "2021-06-11T20:12:56.666Z",
    "updatedAt": "2021-06-12T11:11:56.696Z",
    
}
Run Code Online (Sandbox Code Playgroud)

然后下面的猫鼬查询就可以工作:

await BusinessModel.updateOne(
        {
            '_id': Mongoose.Types.ObjectId(businessId),
            'testimonials._id': Mongoose.Types.ObjectId('60c4918d74c30165ba585c14')
        },
        {
            $set: { 'testimonials.$.authorName' : 'new author name' } 
        }
    );
Run Code Online (Sandbox Code Playgroud)

另请参阅https://docs.mongodb.com/drivers/node/fundamentals/crud/write-operations/embedded-arrays/