В настоящее время я использую следующий код для обновления свойств документов из соответствующих DTO в пакете:
List<User> users = ...;
BulkOperations ops = mongoTemplate.bulkOps(BulkMode.UNORDERED, "users");
for (User user : users) {
Update update = new Update();
if (user.getName() != null) {
update.set("name", user.getName());
}
if (user.getEmail() != null) {
update.set("email", user.getEmail());
}
if (user.getAddress() != null) {
update.set("address", user.getAddress());
}
if (!update.getUpdateObject().isEmpty()) {
ops.updateOne(query(where("_id").is(user.getId())), update);
}
}
BulkWriteResult result = ops.execute();
Я ожидаю, что выше logi c предоставляется Spring Data MongoDB (я использую v2. 2.5), однако я не смог найти ничего, чтобы express было так просто:
...
for (User user : users) {
ops.updateOne(user);
}
...
Есть идеи, как сделать это так коротко и красиво?
Обновление от 19.04.2020:
Только что найдено сообщение Spring Data Mon go обновить ненулевые поля объекта , из которого я пришел к следующему решению :
static class DocumentUpdateOperation extends GenericEntity {
Query query;
Update update = new Update();
}
/**
* Given function collects all non-null properties from given object and constructs {@link Update} instance that
* sets these properties.
*/
DocumentUpdateOperation fromProperties(Object obj) {
DocumentUpdateOperation operation = new DocumentUpdateOperation();
ReflectionUtils.doWithFields(obj.getClass(), field -> {
if (Modifier.isStatic(field.getModifiers())) {
return;
}
field.setAccessible(true);
Object value = field.get(obj);
if (value != null) {
if (field.getName().equals("id")) {
operation.query = query(where("_id").is(value));
} else {
operation.update.set(field.getName(), mongoTemplate.getConverter().convertToMongoType(value));
}
}
});
if (operation.query == null) {
throw new IllegalArgumentException("ID is null for entity " + obj);
}
if (operation.update.getUpdateObject().isEmpty()) {
throw new IllegalArgumentException("At least one property should be non-null for entity " + obj);
}
return operation;
}
...
DocumentUpdateOperation operation = fromProperties(user);
UpdateResult result = mongoTemplate.updateFirst(operation.query, operation.update, "users");
PS Проблема связана с Spring Data MongoDB и массовым обновлением .