Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Spring Boot Mongo Upsert elements in an array

Want to understand how to perform an upsert operation in an array for a given document in MongoDB.

I have the following json document

  {
        "firstName": "John",
        "lastName": "Paul",
        "contact": {
            "contactGroup":"Business",
            "myContacts": [{
                    "name": "Jeff",
                    "phone": "222 - 572 - 8754"
                },
                {
                    "name": "Joe",
                    "phone": "456 - 875 - 4521"
                }
            ]
        }
    }

I want to perform the upsert operation at the following levels:

  1. firstName
  2. myContacts array

Below is the code snippet that I have worked on. currently, I am using MongoDB's addtoSet operator for myContacts but the behavior seems to perform only adds a value to an array unless the value is already present.

Person class:

@Document
public class Person{

    @Id
    private String id;
    private String firstName;
    private String lastName;
    private Contact contact;
    //Setter and Getter methods
}

Contact class:

public class Contact{
    private String contactGroup;
    private List<MyContacts> myContacts;

    //Setter & Getter methods
}

MyContacts class:

public class MyContacts{

    private String contactName;
    private String contactPhone;

    //Setter and Getter methods
}

ContactsUpdate:

public class ContacsUpdate {

@Autowired
private MongoOperations mongoOps;


    // This method receives list of person objects
    public void upsertMongoContact(List<Person> persons) {

        for (Person person : persons) {

            Update updateCmd = new Update();
            Query query = new Query();
            query.addCriteria((Criteria.where("firstName").is((person.firstName()))));

            for (MyContacts contact : person.getContact().getmyContacts()) {
                updateCmd.addToSet("contact.myContacts.", contact);
            }
            mongoOps.findAndModify(query, updateCmd, FindAndModifyOptions.options().upsert(true), Person.class);
        }
    }

}

Is there any way of updating mycontacts array based on the name. If not perform an insert operation.

like image 689
user8363477 Avatar asked Jan 02 '18 15:01

user8363477


1 Answers

Upsert into array is not possible.

So to simulate upsert for array for a happy path scenario, you'll have to do it in 2 different updates.

The code below will look for array element with matching name, when found it will update the matched element with newer phone number; if not found it will insert a new array element with name and phone number.

In essence we first try to locate array element with matching name and try to set the phone value when it succeeds the modified count should be greater than 0. If it zero we have to insert a new document in the array which makes use of push for this. This will do an upsert with new array element.

Something like in Spring Mongo 2.0.2 version

 public void upsertMongoContact(List<Person> persons) {

    for (Person person : persons) {
        for (MyContacts contact : person.getContact().getmyContacts()) {
            Query sQuery = new Query();
            Criteria sCriteria = Criteria.where("firstName").is((person.firstName()));
            sCriteria.and("contact.myContacts.name").is(contact.name());
            sQuery.addCriteria(sCriteria);
            Update sUpdate = new Update();
            sUpdate.set("contact.myContacts.$.phone", person.phone());
            UpdateResult sUpdateResult = mongoOps.updateFirst(sQuery, sUpdate, Person.class);
            if (sUpdateResult.getModifiedCount() == 0) {
                Query pQuery = new Query();
                Criteria pCriteria = Criteria.where("firstName").is((person.firstName()));
                pQuery.addCriteria(pCriteria);
                Update pUpdate = new Update();
                pUpdate.push("contact.myContacts", contact);
                mongoOps.updateFirst(pQuery, pUpdate, Person.class);
            }
        }
    }
}

Reference : Updating nested array document in MongoDB

like image 147
s7vr Avatar answered Sep 29 '22 04:09

s7vr