Let's say I want to multiply all nested values by 10.
{
foos: [
{ val: 1 },
{ val: 10 },
{ val: 5 },
]
}
// to
{
foos: [
{ val: 10 },
{ val: 100 },
{ val: 50 },
]
}
Since we reuse the existing field values, I assume I will have to use aggregation operators.
Here some attempts:
// Does not work, since it it unwinds the values from their parent object.
coll.updateMany({}, [
{$set: {
foos: {$map: {
input: '$foos',
as: 'foo',
in: {$multiply: ['$$foo.val', 10]}
}}
}}
])
// MongoServerError: $multiply only supports numeric types, not string
coll.updateMany({}, [
{
$set: {
'foos.val': {$multiply: ['$foos.$.val', 10]}
}
}
])
Is this possible without fetching the doc, and proceeding to the update with a JS loop?
Something like:
coll.updateMany({}, [
{
$set: {
foos: {
$map: {
input: '$foos',
as: 'foo',
in: {
$project: {
blackMagicToSpreadtheOriginalFoo: '$$foo', // FIXME
val: { $multiply: ['$$foo.val', 10] }
}
}
}
}
}
}
])
CodePudding user response:
In this case, why do you need: blackMagicToSpreadtheOriginalFoo: '$$foo', // FIXME
? Why not simply:
coll.updateMany({},
[
{
$set: {
foos: {
$map: {
input: "$foos",
in: {val: {$multiply: ["$$this.val", 10]}}
}
}
}
}
])
See how it works on the playground example
In case you have other keys inside etch item, just use $mergeObjects
:
coll.updateMany({},
[
{
$set: {
foos: {
$map: {
input: "$foos",
in: {
$mergeObjects: [
"$$this",
{val: {$multiply: ["$$this.val", 10]}}
]
}
}
}
}
}
])
See how it works on the playground example - with keys