前面章节介绍了如何更新 MongoDB 中符合条件的文档,下面介绍 upsert 操作。
与执行 updateFirst 操作相关,你也可以执行 “upsert” 操作。
upsert 操作逻辑为,如果没有找到与查询相匹配的文档,就会执行插入操作,被插入的文档是查询文档和更新文档的组合。否则,什么也不做。
提示:这种操作是不是非常符合我们某些需要保证在一定条件下只能有一个文档的情况。
下面的例子展示了如何使用 upsert 方法:
(1)Person 实体
package com.hxstrive.springdata.mongodb.entity; import lombok.Builder; import lombok.Data; import lombok.ToString; import org.springframework.data.annotation.TypeAlias; import org.springframework.data.mongodb.core.mapping.Document; /** * 用户 * @author hxstrive.com */ @Document("my_person") @TypeAlias("pers") @Data @Builder @ToString public class Person extends Contact { /** ID,自动映射到 MongoDB 的 _id 字段 */ private String id; /** 姓名 */ private String name; /** 年龄 */ private int age; }
(2)客户端,验证 upsert 操作的用法。
package com.hxstrive.springdata.mongodb; import com.hxstrive.springdata.mongodb.entity.Person; import org.junit.jupiter.api.Test; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.boot.test.context.SpringBootTest; import org.springframework.data.mongodb.core.MongoTemplate; import org.springframework.data.mongodb.core.query.Update; import static org.springframework.data.mongodb.core.query.Criteria.where; import static org.springframework.data.mongodb.core.query.Query.query; @SpringBootTest class UpsertTest { @Autowired private MongoTemplate mongoTemplate; @Test void contextLoads() { // 删除集合,便于观察数据 mongoTemplate.dropCollection(Person.class); // 查询是否存在 name=hxstrive 且 age=30 的文档,如果没有则执行插入操作;否则,什么也不做 mongoTemplate.upsert(query(where("name").is("hxstrive").and("age").is(30)), new Update().setOnInsert("id", 1000), Person.class); // 查看输出结果 Person person = mongoTemplate.findOne(query(where("id").is(1000)), Person.class); System.out.println(person); // 验证,如果文档存在,则什么也不做 mongoTemplate.upsert(query(where("name").is("hxstrive").and("age").is(30)), new Update().setOnInsert("id", 2000), Person.class); // 查看输出结果 person = mongoTemplate.findOne(query(where("id").is(1000)), Person.class); System.out.println(person); } }
运行客户端,输出如下:
Person(id=1000, name=hxstrive, age=30) Person(id=1000, name=hxstrive, age=30)