mongodb - 一次更新多个 - 但部分 - 对象字段而不替换整个文档(Spring 3.1 和 MongoDB 的 MongoTemplate)

标签 mongodb spring-3

我试图同时更新“用户”文档中的多个字段。但是,我只想更新一些字段而不是替换整个文档,而后者是我似乎无法避免的。我执行此操作的方法如下所示:

public void mergeUser(User user) {
    Update mergeUserUpdate = new Update();
    mergeUserUpdate.set("firstName", user.getFirstName());
    mergeUserUpdate.set("lastName", user.getLastName());
    mergeUserUpdate.set("username", user.getUsername());

    mongoTemplate.updateFirst(new Query(Criteria.where("_id").is(user.getId())), mergeUserUpdate, User.class);
}

我的用户对象确实包含其他字段 - password 字段就是其中之一 - 但如果在它被立即替换为空字符串或完全删除之前将其设置为一个值。所以在数据库中,这个:

{
  "_id" : ObjectId("4fc34563c3276c69248271d8"),
  "_class" : "com.test.User",
  "password" : "d26b7f5c0ed888e46889dd1e3d217816d070510596f495e156e9efe4b035fec5a1fe1be643955359",
  "username" : "john@gmail.com",
  "alias" : "john"
}

在我调用 mergeUser 方法后被替换为:

{
  "_id" : ObjectId("4fc34563c3276c69248271d8"),
  "_class" : "com.test.User",
  "username" : "john@gmail.com",
  "firstName" : "John",
  "lastName" : "Doe",
  "address" : {
    "addressLine1" : ""
  }
}

如果我查看 Update 对象,我会看到它包含以下内容:

{$set={firstName=John, lastName=Doe, username=john@gmail.com}}

这对我来说是正确的,根据我对 MongoDB $set 函数的理解,这应该只设置指定的值。因此,我希望密码字段保持不变,并相应地添加或更改其他字段。

作为一个一般性的讨论点,我最终试图实现某种“合并”功能,Spring 将自动神奇地检查所提供的用户对象中存在哪些字段,并且只使用填充的值更新数据库在,不是所有领域。我认为这在理论上应该是可能的。有人知道执行此操作的好方法吗?

为了以防万一,这是我的用户对象:

/**
 * Represents an application user.
 */
@Document(collection = "users")
public class User {

    @Id
    private String id;

    @NotEmpty( groups={ChangePasswordValidationGroup.class} )
    private String password;

    @Indexed
    @NotEmpty
    @Email
    private String username;

    private String firstName;

    private String lastName;

    private Date dob;

    private Gender gender;

    private Address address;

    public enum Gender {
        MALE, FEMALE
    }

    // /////// GETTERS AND SETTERS ///////////

    public String getFirstName() {
        return firstName;
    }

    public void setFirstName(String firstName) {
        this.firstName = firstName;
    }

    public String getLastName() {
        return lastName;
    }

    public void setLastName(String lastName) {
        this.lastName = lastName;
    }

    public String getId() {
        return id;
    }

    public void setId(String id) {
        this.id = id;
    }

    public Date getDob() {
        return dob;
    }

    public void setDob(Date dob) {
        this.dob = dob;
    }

    public String getUsername() {
        return username;
    }

    public void setUsername(String username) {
        this.username = username;
    }

    public Gender getGender() {
        return gender;
    }

    public void setGender(Gender gender) {
        this.gender = gender;
    }

    public String getPassword() {
        return password;
    }

    public void setPassword(String password) {
        this.password = password;
    }

    public String getAlias() {
        return alias;
    }

    public void setAlias(String alias) {
        this.alias = alias;
    }

    public Address getAddress() {
        return address;
    }

    public void setAddress(Address address) {
        this.address = address;
    }
}

最佳答案

上面的代码确实工作得很好。我犯了一个愚蠢的错误,在正确更新后我继续保存用户对象,用新文档替换它。

关于mongodb - 一次更新多个 - 但部分 - 对象字段而不替换整个文档(Spring 3.1 和 MongoDB 的 MongoTemplate),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/10782684/

相关文章:

java - 如何让单元测试在 java 7 : java. lang.VerifyError 中运行:在分支目标处期望堆栈映射框架

java - 了解 Spring @Autowired 的用法

mongodb - 将另一个文档中的文档 ID 保存为 ObjectId 或 String 是否更好?

ruby-on-rails-3 - Mongoid,与带有时间戳和版本控制的嵌入式文档混淆?

mongodb - 使用 MongoDB 和 Golang 通过聚合和查找查找重复项

java - 带有多个文件的 Spring 3 @ImportResource

maven - java.lang.NoSuchMethodError : org. springframework.beans.factory.xml.XmlReaderContext.getResourceLoader()Lorg/springframework/core/io/ResourceLoader

java - 可以对 spring rest 调用进行 junit 测试吗?

c# - 使用 C# 驱动程序将新字段插入 MongoDB 中的现有集合(许多文档)

mongodb - 有索引的搜索时间 > 无索引