I have got a collection aTable with 2 records:
{
\"title\" : \"record 1\",
\"fields\" : [
{
\"_id\" : 1,
Starting Mongo 4.2, db.collection.update() can accept an aggregation pipeline, finally allowing the update of a field based on its current value, and thus using a query instead of javascript:
// {
// title: "record 1",
// fields: [
// { _id: 1, items: [1] },
// { _id: 2, items: [2, 3, 4] },
// { _id: 3, items: [5] }
// ]
// }
db.collection.update(
{},
[{ $set: {
fields: { $map: {
input: "$fields",
as: "x",
in: {
_id: "$$x._id",
items: { $map: {
input: "$$x.items",
as: "y",
in: { item: "$$y", key: 0 }
}}
}
}}
}}],
{ multi: true }
)
// {
// title: "record 1",
// fields: [
// { _id: 1, items: [ { item: 1, key: 0 } ] },
// { _id: 2, items: [ { item: 2, key: 0 }, { item: 3, key: 0 }, { item: 4, key: 0 } ] },
// { _id: 3, items: [ { item: 5, key: 0 } ] }
// ]
// }
The first part {} is the match query, filtering which documents to update (in this case all documents).
The second part [{ $set: { fields: { $map: { ... } } }] is the update aggregation pipeline (note the squared brackets signifying the use of an aggregation pipeline):
[1, 2] by [{ item: 1, key: 0 }, { item: 2, key: 0 }].{ multi: true }, otherwise only the first matching document will be updated.