简体   繁体   English

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

[英]MongoDB: How do I update a single subelement in an array, referenced by the index within the array?

I'm trying to update a single subelement contained within an array in a mongodb document.我正在尝试更新 mongodb 文档中数组中包含的单个子元素。 I want to reference the field using its array index (elements within the array don't have any fields that I can guarantee will be unique identifiers).我想使用它的数组索引来引用该字段(数组中的元素没有任何我可以保证将是唯一标识符的字段)。 Seems like this should be easy to do, but I can't figure out the syntax.看起来这应该很容易做到,但我无法弄清楚语法。

Here's what I want to do in pseudo-json.这是我想在伪 json 中做的事情。

Before:前:

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

After:后:

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

Seems like the query should be something like this:似乎查询应该是这样的:

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

But this doesn't work.但这不起作用。 I've spent way too long searching the mongodb docs, and trying different variations on this syntax (eg using $slice , etc.).我花了太长时间搜索 mongodb 文档,并尝试了此语法的不同变体(例如使用$slice等)。 I can't find any clear explanation of how to accomplish this kind of update in MongoDB.我在 MongoDB 中找不到关于如何完成这种更新的任何明确解释。

As expected, the query is easy once you know how.正如预期的那样,一旦您知道如何查询,查询就很容易了。 Here's the syntax, in python:这是python中的语法:

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

Update of an array element referenced by an index (eg 1 ) in Mongo Shell can also be done by directly indicating the index value: Mongo Shell 中索引(例如 1 )引用的数组元素的更新也可以通过直接指示索引值来完成:

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

In mongo style, using '$' positional operator.在 mongo 风格中,使用 '$' 位置运算符。 Check out this link for details.查看此链接了解详情。

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

When it's required to update an array element without knowing it's actual index but having a unique identifier of the element:当需要更新数组元素而不知道它的实际索引但具有元素唯一标识符时:

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

Here "bucket.commentId" is the unique identifier of an array element.这里"bucket.commentId"是数组元素的唯一标识符。

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

A neat way to do it in Javascript, with backticks, is:在 Javascript 中使用反引号的一种巧妙方法是:

 const index = 1;

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

When it's required to update an array element without knowing it's an actual index but having a unique identifier of the element当需要更新数组元素而不知道它是实际索引但具有元素的唯一标识符时

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

You can use the updateOne function of mongoDB passing the index of the element in array, if the key of old content B is "value" per example:您可以使用mongoDB的updateOne函数传递数组中元素的索引,如果旧内容B的键是“值”每个示例:

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

the command should be like this:命令应该是这样的:

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

If you want to update the authorName of the testimonial having _id = 60c4918d74c30165ba585c14 from the following document:如果您想从以下文档更新具有 _id = 60c4918d74c30165ba585c14 的推荐书的 authorName:

"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",
    
}

Then the following mongoose query works:然后下面的猫鼬查询工作:

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

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

Ok, I'm looking for a solution for this problem and every anwser that I found until now is like "you do array.2 or do array.5 or array.anyotherpredefinedfixedvalue..."and I think this is not ideal at all. 好的,我正在寻找解决这个问题的方法,直到现在我发现的每个答案都像“您执行array.2或array.5或array.anyotherpredefinedfixedvalue ...”,我认为这根本不理想。 I want to do ARRAY.X ... I want to change the value of an object inside an array in which the position is X , not 5 or 3 or any fixed value. 我想做ARRAY.X ...我想更改数组中对象的值,该数组的位置是X ,而不是5或3或任何固定值。 I dont know any other information about the array/object (it might be empty or it may contain some information inside). 我不知道有关数组/对象的任何其他信息(它可能为空或其中可能包含一些信息)。 I've been trying everything and this is getting me crazy right now. 我一直在尝试所有事情,这现在让我发疯。 I cannot change the 2 or 5 for an "x" variable, it simply doesnt work. 我无法为“ x”变量更改2或5,它根本无法正常工作。 Can someone please explain how can I do this? 有人可以解释一下我该怎么做吗?

If you have a "plain" array containing simple strings, this did the trick:如果你有一个包含简单字符串的“普通”数组,这就可以了:

db.paintings.insertMany([
  {_id: 1, colors: ["red", "blue", "green"]},
  {_id: 2, colors: ["red", "yellow"]}

db.paintings.updateMany(
  {colors: "red"},
  {$set: {"colors.$": "magenta"}})

the positional $ operator acts as a placeholder for the first element that matches the query document Source位置 $ 运算符充当与查询文档匹配的第一个元素的占位符

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM