问题
I'm working on Django which uses MongoDB. One of collections has the following structure:
{
"inspectionType" : {
"id" : "59a79e44d12b52042104c1e8",
"name" : "Example Name",
"inspMngrsRole" : [
{
"id" : "55937af6f3de6c004bc42862",
"type" : "inspectorManager",
"is_secret_shoper" : false
}
],
"scopes" : {
"56fcf6736389b9007a114b10" : {
"_cls" : "SomeClass",
"id" : "56fcf6736389b9007a114b10",
"name" : "Example Name",
"category" : "Example Category"
},
}
}
}
I need to update field "_cls" ("inspectionType.scopes.._cls") for all documents in the collection. The problem is the scope_id is dynamic and unique for each scope. Is it possible to use db.collection.update for that? And how should the path to the field look like?
Update: MongoDB version: 3.6.7
回答1:
You can update using an aggregation (if you are using MongoDB version lesser than 4.2) plus an update operation or the updateMany
method (if using version 4.2 or later) as follows:
# 1
var NEW_VALUE = "some new value" // the value to be updated
db.collection.aggregate( [
{
$addFields: {
"inspectionType.scopes": { $objectToArray: "$inspectionType.scopes" }
}
},
{
$addFields: {
"inspectionType.scopes.v._cls": NEW_VALUE
}
},
{
$addFields: {
"inspectionType.scopes": { $arrayToObject: "$inspectionType.scopes" }
}
}
] ).forEach( doc => db.scopes.updateOne( { _id: doc._id }, { $set: { "inspectionType.scopes": doc.inspectionType.scopes } } ) )
Starting MongoDB version 4.2 the updateMany
can use an aggregation pipeline for the update operation; see Update with Aggregation Pipeline.
# 2
db.collection.updateMany(
{ },
[
{
$set: {
"inspectionType.scopes": { $objectToArray: "$inspectionType.scopes" }
}
},
{
$set: {
"inspectionType.scopes.v._cls": NEW_VALUE
}
},
{
$set: {
"inspectionType.scopes": { $arrayToObject: "$inspectionType.scopes" }
}
}
]
)
来源:https://stackoverflow.com/questions/61041855/update-nested-field-if-a-path-to-it-isnt-constant