简体   繁体   English

数组中的Spring Boot Mongo Upsert元素

[英]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. 想了解如何在MongoDB中为给定文档在数组中执行upsert操作。

I have the following json document 我有以下JSON文档

  {
        "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: 我要在以下级别执行upsert操作:

  1. firstName 名字
  2. myContacts array myContacts数组

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. 当前,我使用MongoDB的addtoSet运算符作为myContacts,但是该行为似乎只会向数组添加一个值,除非该值已经存在。

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: MyContacts类:

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. 有什么方法可以根据名称更新mycontacts数组。 If not perform an insert operation. 如果不执行插入操作。

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. 因此,要模拟阵列的上调以获取满意的路径,您必须在2个不同的更新中进行。

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. 本质上,我们首先尝试查找具有匹配名称的数组元素,并尝试在其成功后设置电话值,修改后的计数应大于0。如果为零,则必须在数组中插入一个新文档,该文档使用push for这个。 This will do an upsert with new array element. 这将对新的数组元素进行更新。

Something like in Spring Mongo 2.0.2 version 类似于Spring Mongo 2.0.2版本

 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 参考: 在MongoDB中更新嵌套数组文档

I believe the problem is in the addSet part. 我相信问题出在addSet部分。 Try this. 尝试这个。 Remove the for loop for addToSet. 删除addToSet的for循环。 Replace with below 用下面替换

updateCmd.addToSet("myContacts", person)

Hope this helps. 希望这可以帮助。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM