Reputation: 78
I want to use $set
to copy a value which is nested in an array of objects to each object, but instead of copying that single value, it projects all the elements in an array. This is what I tried:
db.things.insertOne(
{
name: 'first',
items: [
{ value: 1 },
{ value: 2 }
]
}
)
db.things.updateMany(
{},
[
{"$set": {"items.value_copy": "$items.value"}}
]
)
Outcome:
{
"_id": {
"$oid": "5e527707f3ae2e9f7adb6e1c"
},
"name": "first",
"items": [
{
"value": 1,
"value_copy": [
1,
2
]
},
{
"value": 2,
"value_copy": [
1,
2
]
}
]
}
Expected outcome:
{
"_id": {
"$oid": "5e527707f3ae2e9f7adb6e1c"
},
"name": "first",
"items": [
{
"value": 1,
"value_copy": 1
},
{
"value": 2,
"value_copy": 2
}
]
}
db.version();
4.2.3
Any idea how to get to my intended goal?
Upvotes: 2
Views: 1388
Reputation: 17915
That issue is because $items.value
would get a list of values at items.values
from all documents. You can use aggregation pipeline in update operation, Which is introduced in MongoDB v4.2
to re-write the entire items
array with new field added to its each object :
db.thingsNew.update({}, [{
$set: {
items: {
$map: {
input: "$items",
as : 'each',
in: {
"value": "$$each.value",
"value_copy": "$$each.value"
}
}
}
}
}], { multi: true })
Upvotes: 2
Reputation: 13103
Walkaround. We use MongoDb Aggregation with $map
to add value_copy
field and $out
operator override the collection.
db.things.aggregate([
{
$set: {
items: {
$map: {
input: "$items",
in: {
"value": "$$this.value",
"value_copy": "$$this.value"
}
}
}
}
},
{
$out: "things"
}
])
Upvotes: 0