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

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 (e.g. using $slice, etc.). I can't find any clear explanation of how to accomplish this kind of update in MongoDB.

142844 次浏览

As expected, the query is easy once you know how. Here's the syntax, in python:

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

在 mongo 样式中,使用“ $”位置运算符。 查看此 链接了解详细信息。

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

Update of an array element referenced by an index (e.g. 1 ) in Mongo Shell can also be done by directly indicating the index value:

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

如果 旧内容 B的键为“ value”,那么可以使用 mongoDB 的 updateOne 函数传递数组中元素的索引:

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

在 Javascript 中,一个简单的方法是:

 const index = 1;


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

When it's required to update an array element without knowing it's actual index but having a 元素的唯一标识符:

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

这里的 abc0是一个数组元素的唯一标识符。

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

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

If you want to update the authorName of the testimonial having _id = 60c4918d74c30165ba585c14 from the following document:

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

如果您有一个包含简单字符串的“普通”数组,那么这个方法就奏效了:

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


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

位置 $运算符充当与查询文档匹配的第一个元素的占位符 来源