Much faster that downloading everything but still sub-optimal since you cannot use an index.
But since
there is no way to use an index.
Carefully read about the attribute pattern and get rid of these numbers as keys.
Now that we have a way to get only the documents to update, you are able to do, with a python loop, a sub-optimal bulk write with one updateOne operation for each _id that you have to update.
I still have to work on how to do it directly with aggregation but it needs some work. It will involve, I think, some $filter (to only keep v.rating:.80 from _tmp.root) , an $arrayToObject, a $mergeObject (to update $$ROOT) and then a $merge stage to commit the update. UGLY
Carefully read about the attribute pattern and get rid of these numbers as keys.
I had some time to play with the next stages for the update. The stages are to be added between the $match and the $unset.
/* filter to only keep the dynamic key to update */
filter = { "$set" : {
"_tmp.filtered" : { "$filter" : {
"input" : "$_tmp.root" ,
"cond" : { "$eq" : [ "$$this.v.rating" , ".80" ] }
} }
} }
/* extract first and only element since it is easier to update */
extract = { "$set" : {
"_tmp.extracted" : { "$arrayElemAt" : [ "$_tmp.filtered" , 0 ] }
} }
/* update the extracted v: to desired value */
update = { "$set" : {
"_tmp.updated" : [ {
"k" : "$_tmp.extracted.k" ,
"v" : { "rating" : ".90" , "refreshed" : "$_tmp.extracted.v.refreshed" }
} ]
} }
/* make the updated dynamic an object ready to merge */
objectify = { "$set" : {
"_tmp.object" : { "$arrayToObject" : "$_tmp.updated" }
} }
/* The magic replace that really update the original dynamic field in the root object. */
replace = { "$replaceWith" : {
"$mergeObjects" : [ "$$ROOT" , "$_tmp.object" ]
} }
You could surely implements all the above $set stages into one big ugly very deep single expression of the $replaceWith that does not use _tmp variables, that is hard to read and hard to debug but I won’t.
The next stage commits the result back to the original stored document. It has to be performed after the $unset otherwise the temporary values will also be stored back.