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


79

我正在尝试更新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中完成这种更新的任何明确解释。

Answers:


74

不出所料,一旦您知道如何进行查询。这是python中的语法:

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

13
这在哪里记录?
ROROROOROROR

这样最终创建了一个具有相同名称的对象,而不是更新数组
Kisinga

这绝对是一个过时的答案。
Mark Odey

48

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

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

如果我们不知道索引怎么办?
Muhammad Shahzad

42

在mongo风格中,使用“ $”位置运算符。查看此链接以获取详细信息。

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

那是最好的答案!
Bogdan Kobylynskyi

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

5

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

// 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.


In Mongo shell with findAndModify, double quotes in $set does not work for me. I have to use single quotes for the field.
WesternGun

4

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:

[
...
"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"}})

5
How do we do it if we don't know the index ?
Shaharyar Kirmani

3

A neat way to do it in Javascript, with backticks, is:

 const index = 1;

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

0

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
  }
)
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.