Piotr Żak
Piotr Żak

Reputation: 2403

MongoDB how update element in array using Spring Query Update

In my project I'm using SpringBoot 1.3.2 and org.springframework.data.mongodb.core.query.*

I'm trying to update element in array, in my main object i have array looking like this:

"sections" : [
        {
                "sectionId" : "56cc3c908f5e6c56e677bd2e",
                "name" : "Wellcome"
        },
        {
                "sectionId" : "56cc3cd28f5e6c56e677bd2f",
                "name" : "Hello my friends"
        }
]

Using Spring I want to update name of record with sectionId 56cc3c908f5e6c56e677bd2e

I was trying to to this like that but it didn't work

  Query query = Query.query(Criteria
                .where("sections")
                .elemMatch(
                        Criteria.where("sectionId").is(editedSection.getId())
                )
        );
        Update update = new Update().set("sections", new BasicDBObject("sectionId", "56cc3c908f5e6c56e677bd2e").append("name","Hi there"));
        mongoTemplate.updateMulti(query, update, Offer.class);

It create something like:

"sections" : {
         "sectionId" : "56cc3c908f5e6c56e677bd2e",
         "name" : "Hi there"
 }

But this above is object { } I want an array [ ], and I don't want it remove other elements.

Can any body help me how to update name of record with sectionId 56cc3c908f5e6c56e677bd2e using Spring

Upvotes: 7

Views: 22167

Answers (3)

GtdDev
GtdDev

Reputation: 928

Thats my solution for this problem:

  public Mono<ProjectChild> UpdateCritTemplChild(
       String id, String idch, String ownername) {

    Query query = new Query();
    query.addCriteria(Criteria.where("_id")
                              .is(id)); // find the parent
    query.addCriteria(Criteria.where("tasks._id")
                              .is(idch)); // find the child which will be changed

    Update update = new Update();
    update.set("tasks.$.ownername", ownername); // change the field inside the child that must be updated

    return template
         // findAndModify:
         // Find/modify/get the "new object" from a single operation.
         .findAndModify(
              query, update,
              new FindAndModifyOptions().returnNew(true), ProjectChild.class
                       )
         ;

  }

Upvotes: 0

abhinav kumar
abhinav kumar

Reputation: 1803

Can use BulkOperations approach to update list or array of document objects

BulkOperations bulkOps = mongoTemplate.bulkOps(BulkMode.UNORDERED, Person.class);
for(Person person : personList) {
    Query query = new Query().addCriteria(new Criteria("id").is(person.getId()));
    Update update = new Update().set("address", person.setAddress("new Address"));
    bulkOps.updateOne(query, update);
}
BulkWriteResult results = bulkOps.execute();

Upvotes: 2

chridam
chridam

Reputation: 103325

You essentially want to replicate this mongo shell update operation:

db.collection.update(
    { "sections.sectionId": "56cc3c908f5e6c56e677bd2e" },
    {
        "$set": { "sections.$.name": "Hi there" }
    },
    { "multi": true }
)

The equivalent Spring Data MongoDB code follows:

import static org.springframework.data.mongodb.core.query.Criteria.where;
import static org.springframework.data.mongodb.core.query.Query;
import static org.springframework.data.mongodb.core.query.Update;

...

WriteResult wr = mongoTemplate.updateMulti(
    new Query(where("sections.sectionId").is("56cc3c908f5e6c56e677bd2e")),
    new Update().set("sections.$.name", "Hi there"),
    Collection.class
);

Upvotes: 20

Related Questions