使用Spring Data MongoDB(MongoOperations)进行部分实体Map和更新

jtjikinw  于 2022-11-28  发布在  Go
关注(0)|答案(4)|浏览(215)

在我的数据库中,我有一个类似于以下内容的文档

{
    "_id" : ObjectId("5864ddd8e38112fd70b89893"),
    "_class" : "com.apic.models.UserReg",
    "name" : "Bijay",
    "email" : "apic.apps@gmail.com",
    "psd" : "16d932a5a3da90cc6afd831016b5a6821f0badf7e2c624159205924433613c3a",
    "activationToken" : "fe8376ea2dbdf61ebc0f11a2361d741ba3178362d5bf876cf47e6a126bc5b39c",
    "verified" : false
}

我也有一颗豆子看起来像这样

public class User {
  @Id
  private int id;
  private String name;
  private String email;

  // getter/setter methods

}

因此,当我尝试调用MongoOperationssave()方法时,它会替换所有缺少的属性,如psd、verified和activationToken。

mongoOperations.save(user, COLLECTION);

有没有什么方法可以让我只更新models类中的现有属性,而让其他属性保持原样?

hwamh0ep

hwamh0ep1#

是的,您可以呼叫选择性更新

Query query = new Query(new Criteria("id").is(user.getId()));
Update update = new Update().set("name", user.getName()).set("email", user.getEmail());
mongoOperations.updateFirst(query, update, COLLECTION);
6mw9ycah

6mw9ycah2#

如果你想设置任意数量的字段(但不覆盖其他字段),你可以添加一个函数到你的模型中,把它变成Map
从那里,您可以删除所有null值,然后将每个具有值的字段添加到$set操作中。

Map<String, Object> objectMap = user.toMap();
    objectMap.values().removeIf(Objects::isNull);
    Update update = new Update();
    objectMap.forEach(update::set);

    return mongoOperations.findAndModify(
            Query.query(Criteria.where("_id").is(user.getId())), update, User.class);
sqougxex

sqougxex3#

根据@Rossiar的答案,我们可以使用MongoConverter而不是Jackson

Document document = new Document();
mongoOperations.getConverter().write(user, document);
Update update = new Update();
document.forEach(update::set);
return mongoOperations.findAndModify(
            Query.query(Criteria.where("_id").is(user.getId())), update, User.class);
iyr7buue

iyr7buue4#

最近,我不得不处理上面的问题:“有没有什么方法可以只更新模型类中的现有属性,而让其他属性保持原样?”
前面提到的可接受的答案可以很好地工作,但缺点是必须以编程方式创建每个更新项。如果您有嵌套类,则不必使用点标记法和其他复杂的东西。
我的第一个直觉是使用$set Mongo操作,从一个只包含可更新字段+键的Json创建一个文档,然后将其应用到集合中。虽然它适用于像本问题示例中的结构,但对于嵌套类它将失败。
解决方案是使用Apache BeanUtils copyProperties的增强版本。

  • 从数据库中获取实际的完整记录
  • 使用关键字和可更新数据填充更新Pojo。其余字段应为空。
  • 使用增强版从更新Pojo复制到实际Pojo。
  • 从Pojo创建一个文档(使用SpringMongo的代码如下)
  • 呼叫更新

第一个
有关此方法的完整讨论,请访问Copy non-null properties from one object to another using BeanUtils or similar

相关问题