How to update an object in a array using MongoDB Java Driver?
Asked Answered
V

1

7

Hello I have this document

{
  email: "[email protected]",
  list: [
    {
      "product": "Car",
      "price": 18
    },
    {
      "product": "Boat",
      "price": 20 
    }
  ]
}

I am wondering how to identify the document using the email parameter and update a specific object in the list parameter by finding the product with the "Car" parameter and updating the price to 15 using the MongoDB Java Driver.

Thank you

Varico answered 15/5, 2020 at 22:33 Comment(3)
what do you mean by "identify the document using the email parameter"?. It would be better if you add some explanation about your problem and code you have triedMessere
@komatiraju032 I am not sure how to approach this using the MongoDB Driver and the email key in the JSON object that I have providedVarico
specific object means is there any condition?Messere
C
8

There are two ways to update the nested document of an array field based upon a condition.

(1) Update using the Positional $ Operator:

The positional $ operator acts as a placeholder for the first element that matches the query document, and the array field must appear as part of the query document;i.e., "list.product": "Car". And, secondly only the first matching array element will be updated.

db.collection.updateOne( 
  { email: "[email protected]", "list.product": "Car" }, 
  { $set: { "list.$.price": 15 } } 
)

(2) Update using the Filtered Positional $[identifier] Operator:

The filtered positional operator $[identifier] identifies the array elements that match the arrayFilters conditions for an update operation.

Note the condition on the array field is not required when using the $[identifier] update operator. And, secondly all the matching array elements ("product": "Car") will be updated.

db.collection.updateOne( 
  { email: "[email protected]" }, 
  { $set: { "list.$[ele].price": 15 } },
  { arrayFilters: [ { "ele.product": "Car" } ] }
)


Update using MongoDB Java Driver:

Case 1:

Bson filter = and(eq("email", "[email protected]"), eq("list.product", "Car"));
Bson update = set("list.$.price", 15);
UpdateResult result = coll.updateOne(filter, update);

Case 2:

Bson filter = eq("email", "[email protected]");
UpdateOptions options = new UpdateOptions()
                              .arrayFilters(asList(eq("ele.product", "Car")));
Bson update = set("list.$[ele].price", 15);
UpdateResult result = coll.updateOne(filter, update, options);

Reference: MongoDB Java Driver

Calcification answered 16/5, 2020 at 7:21 Comment(3)
To complete this great anwser, if you don't want to filter the elements in there array (aka if you want to update all the entries of the array), you should use Updates.set("list.$[].fieldToSet", newValue)Renteria
Can you please also tell us how to replace any single object entirely from the list in the example above? Like in your answer you are using $set to update only price of an element in the array of lists. What if we need to replace this object { "product": "Car", "price": 18 }, entirely with new one?Phocaea
@Phocaea You can update more than one field using the $set update operator.Calcification

© 2022 - 2024 — McMap. All rights reserved.