Хотите понять, как выполнить операцию upsert в массиве для данного документа в MongoDB.
У меня есть следующий документ json
{
"firstName": "John",
"lastName": "Paul",
"contact": {
"contactGroup":"Business",
"myContacts": [{
"name": "Jeff",
"phone": "222 - 572 - 8754"
},
{
"name": "Joe",
"phone": "456 - 875 - 4521"
}
]
}
}
Я хочу выполнить операцию upsert на следующих уровнях:
- имя
- массив myContacts
Ниже приведен фрагмент кода, над которым я работал. в настоящее время я использую оператор addtoSet MongoDB для myContacts, но поведение, похоже, выполняется, только добавляет значение в массив, если значение уже не присутствует.
Класс персонажа:
@Document
public class Person{
@Id
private String id;
private String firstName;
private String lastName;
private Contact contact;
//Setter and Getter methods
}
Контактное лицо:
public class Contact{
private String contactGroup;
private List<MyContacts> myContacts;
//Setter & Getter methods
}
Класс MyContacts:
public class MyContacts{
private String contactName;
private String contactPhone;
//Setter and Getter methods
}
Обновление контактов:
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);
}
}
}
Есть ли способ обновить массив mycontacts на основе имени. Если нет, выполните операцию вставки.
2 ответа
Вставка в массив невозможна.
Итак, чтобы смоделировать upsert для массива для сценария счастливого пути, вам нужно будет сделать это в двух разных обновлениях.
Приведенный ниже код будет искать элемент массива с совпадающим именем, когда он будет найден, он обновит соответствующий элемент с новым номером телефона; если он не найден, он вставит новый элемент массива с именем и номером телефона.
По сути, мы сначала пытаемся найти элемент массива с совпадающим именем и пытаемся установить значение телефона, когда оно преуспевает, измененное количество должно быть больше 0. Если оно равно нулю, мы должны вставить новый документ в массив, который использует push для этот. Это приведет к обновлению с новым элементом массива.
Что-то вроде версии 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);
}
}
}
}
Ссылка: Обновление документа вложенного массива в MongoDB
Я считаю, что проблема в части addSet. Попробуй это. Удалите цикл for для addToSet. Заменить на ниже
updateCmd.addToSet("myContacts", person)
Надеюсь это поможет.
Новые вопросы
java
Java - это язык программирования высокого уровня. Используйте этот тег, если у вас возникли проблемы с использованием или пониманием самого языка. Этот тег редко используется отдельно и чаще всего используется вместе с [spring], [spring-boot], [jakarta-ee], [android], [javafx], [hadoop], [gradle] и [maven].