I have a collection like that:
{
'_id': objectId,
'uuid': string,
'contexts' object -> (0:"wifi6", 1:"anydesk", _seriablizable_class:"App\\Collection\\Context")
}
actual:
{
"_id": {
"$oid": "6399a76340573591210b9cf3"
},
"uuid": "ae7470a9-af8f-4baf-9981-1581313e3923",
"name": "text",
"description": "text",
"device_info": {},
"contexts": {
"0": "wifi6",
"1": "4g",
"2": "2.4"
"_seriablizable_class": "App\\Device\\Domain\\ValueObject\\ContextCollection"
},
"filter_contexts": [
"0": "wifi6",
"1": "4g",
"2": "2.4"
],
"deleted": false,
"created_at": {
"$date": {
"$numberLong": "1671014243165"
}
},
"updated_at": {
"$date": {
"$numberLong": "1671014243166"
}
}
}
expected:
{
"_id": {
"$oid": "6399a76340573591210b9cf3"
},
"uuid": "ae7470a9-af8f-4baf-9981-1581313e3923",
"name": "text",
"description": "text",
"device_info": {},
"contexts": {
"0": "wifi6",
"1": "4g",
"2": "2.4",
"3": "5G"
"_seriablizable_class": "App\\Device\\Domain\\ValueObject\\ContextCollection"
},
"filter_contexts": [
"0": "wifi6",
"1": "4g",
"2": "2.4",
"3": "5G"
],
"deleted": false,
"created_at": {
"$date": {
"$numberLong": "1671014243165"
}
},
"updated_at": {
"$date": {
"$numberLong": "1671014243166"
}
}
}
I want to update all table, add new field to contexts
named "5G" to any documents that that match with contexts: "wifi6". The difficult is we need to add "5G" to the right index, that depend on "$count" fields in contexts
.
I try to write an update script like this, but it didn't work
db.devices.findAndModify(
{'query':{contexts:"Wifi6"},
'update': {
[
'$group': {
"_id": "$_id",
"count": {
"$sum": {
"$size": { "$objectToArray": "$contexts" }
}
},
contexts: {$first:'$contexts'}
},
'$set': { 'contexts':
{ $mergeObjects: [ { "$count-1": "5G"}, "$contexts" ] }
}
]
}
})
What did i wrong here?
CodePudding user response:
To dynamically create a field name in an existing object, first convert the object to an array, add the new field as a object like {k:"fieldname", v:"value"}
, then convert the array back to an object.
For example, after selecting the documents to be edited, these $addFields
stages would add that field to the contexts object:
{$addFields: {
contexts: {"$objectToArray": "$contexts"}
}},
{$addFields: {
contexts: {
"$concatArrays": [
"$contexts",
[{
k: {$toString: {$sum: [-1,{"$size": "$contexts"}]}},
v: "5G"
}]
]
}
}},
{$addFields: {
contexts: {"$arrayToObject": "$contexts"}
}}