Reputation: 349
I have this collection :
{
"_id" : ObjectId("5ac69e90a9d1a5f3e01a5233"),
"category": "spain",
"products" : [
{
"label" : "uno"
},
{
"label" : "dos"
},
{
"label" : "tres"
}
]
},
{
"_id" : ObjectId("5ac69e90a9d1a5f3e01a5234"),
"category": "england",
"products" : [
{
"label" : "one"
},
{
"label" : "two"
},
{
"label" : "three"
}
]
}
I want to do the following operation : update the label from "one" to "four" of the object with the category england. But I have some troubles to design the most elegant and performant solution :
first solution : I could copy paste and rewrite the entire document with just replacing the one by four second solution where I struggle : I would like to find the element with label equals to one and updates it to four, but I don't know how to do. I don't want to use mongo path index like 'products.O.label' because I can't garantee that the product with label one will be at position 0 in the products array.
Thanks in advance
Upvotes: 1
Views: 60
Reputation: 59456
You could use this one:
db.collection.updateMany(
{ category: "england" },
{ $set: { "products.$[element].label": "four" } },
{ arrayFilters: [{ "element.label": "one" }] }
)
If you prefer and aggregation pipeline it would be this one:
db.collection.updateMany(
{ category: "england" },
[{
$set: {
products: {
$map: {
input: "$products",
in: {
$cond: {
if: { $eq: ["$$this.label", "one"] },
then: { label: "four" },
else: "$$this"
}
}
}
}
}
}]
)
but it might be an overkill, in my opinion.
Upvotes: 2
Reputation: 334
Further, referring to @Wernfried Domscheit, another way using aggregation.
> db.catg1.find();
{ "_id" : ObjectId("5ac69e90a9d1a5f3e01a5233"), "category" : "spain", "products" : [ { "label" : "uno" }, { "label" : "dos" }, { "label" : "tres" } ] }
{ "_id" : ObjectId("5ac69e90a9d1a5f3e01a5234"), "category" : "england", "products" : [ { "label" : "four" }, { "label" : "two two" }, { "label" : "three" } ] }
> db.catg1.aggregate([
... {$unwind:"$products"},
... {$match:{category:"england",
... "products.label":"four"
... }
... },
... ]).forEach(function(doc){
... print(doc._id);
... db.catg1.update(
... {"_id":doc._id},
... { $set:{"products.$[element].label":"one"}},
... {arrayFilters: [{"element.label":"four"}]}
... );
... });
ObjectId("5ac69e90a9d1a5f3e01a5234")
> db.catg1.find();
{ "_id" : ObjectId("5ac69e90a9d1a5f3e01a5233"), "category" : "spain", "products" : [ { "label" : "uno" }, { "label" : "dos" }, { "label" : "tres" } ] }
{ "_id" : ObjectId("5ac69e90a9d1a5f3e01a5234"), "category" : "england", "products" : [ { "label" : "one" }, { "label" : "two two" }, { "label" : "three" } ] }
> db.version();
4.2.6
>
Upvotes: 0