【问题标题】:MongoDB: How do I update a single subelement in an array, referenced by the index within the array?MongoDB:如何更新数组中的单个子元素,由数组中的索引引用?
【发布时间】:2012-07-07 11:52:19
【问题描述】:

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

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

之前:

{
  _id : ...,
  other_stuff ... ,
  my_array : [
    { ... old content A ... },
    { ... old content B ... },
    { ... old content C ... }
  ]
}

之后:

{
  _id : ...,
  other_stuff ... ,
  my_array : [
    { ... old content A ... },
    { ... NEW content B ... },
    { ... old content C ... }
  ]
}

似乎查询应该是这样的:

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

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

【问题讨论】:

    标签: arrays mongodb


    【解决方案1】:

    正如预期的那样,一旦您知道如何查询,查询就很容易了。这是python中的语法:

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

    【讨论】:

    • 这是在哪里记录的?
    • 这最终会创建一个同名对象而不是更新数组
    • 这绝对是一个过时的答案。
    【解决方案2】:

    在 mongo 风格中,使用 '$' 位置运算符。 详情请查看link

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

    【讨论】:

      【解决方案3】:

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

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

      【讨论】:

      • 不知道索引怎么办?
      【解决方案4】:
      db.my_collection.update(
        {_id: ObjectId(document_id), my_array : { ... old content A ... } },
        { $set: { "my_array.$.content" : "NEW content B" } }
      )
      

      【讨论】:

        【解决方案5】:

        如果旧内容B的键是“值”,例如,您可以使用mongoDB的updateOne函数传递数组中元素的索引:

        [
        ...
        "value" : "old content A"
        "value" : "old content B"
        "value" : "old content C"
        ...
        ]
        

        命令应该是这样的:

        db.collection.updateOne({"_id" : "...,"},{$set: {"my_array.1.value": "NEW content B"}})
        

        【讨论】:

        • 不知道索引怎么办?
        【解决方案6】:

        在 Javascript 中使用反引号的一种简洁方法是:

         const index = 1;
        
         ...  {   $set: { [`myArray.${index}.value`]: "new content"}  },  ...
        

        【讨论】:

          【解决方案7】:

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

          // 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")
                  }
              }
          )
          

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

          【讨论】:

          • 在带有 findAndModify 的 Mongo shell 中,$set 中的双引号对我不起作用。我必须为该字段使用单引号。
          • 索引$在哪里设置?
          • 这应该是公认的答案,谢谢!
          【解决方案8】:

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

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

          【讨论】:

            【解决方案9】:

            如果您想从以下文档更新 _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",
                
            }
            

            那么下面的猫鼬查询就起作用了:

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

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

            【讨论】:

              猜你喜欢
              • 2018-09-21
              • 2016-03-14
              • 1970-01-01
              • 1970-01-01
              • 1970-01-01
              • 1970-01-01
              • 2014-03-27
              • 2017-07-02
              • 2019-05-27
              相关资源
              最近更新 更多