导包:
org.springframework.boot:spring-boot-starter-data-mongodb:2.6.7
org.springframework.boot:spring-boot-starter-validation:2.6.7
框架中使用jpa+mongodb,这里记录两种方法操作mongodb,一个是使用mongoTemplate:
实体类:
public abstract class BaseDocument {
@CreatedDate public Date createDate = new Date();
@CreatedBy public String createdBy;
@LastModifiedDate public Date lastModifiedDate = new Date();
@LastModifiedBy public String lastModifiedBy;
}
@EqualsAndHashCode(callSuper = true)
@Document
@Data
@NoArgsConstructor
@AllArgsConstructor
@Builder
@Slf4j
public class Event extends BaseDocument {
@MongoId(value = FieldType.OBJECT_ID)
private String id;
@Indexed private String hostId;
@Pattern(regexp = "^$|^.{4,255}$", message = "title must be in 5~255 characters")
private String title;
@Pattern(regexp = "^$|^[\\w\\W]{4,12225}$", message = "description must be in 5~12225 characters")
private String description;
}
使用mongoRepository的方法:
public interface EventRepository extends MongoRepository<Event, String>, EventRepositoryCustom {
Optional<Event> findById(String eventId);
void removeById(String eventId);
}
如果是一些复杂的情况如聚合,则需要自己写聚合语句:
例如:
@Aggregation(
pipeline = {
" {\n"
+ " $match: {hostId: \"?0\", status: {$in: ['STARTED','APPROVED']}}},\n"
+ " },",
" {\n"
+ " $addFields: {\n"
+ " statusIndex: {\n"
+ " $cond: [\n"
+ " { $eq: [\"$event.status\", \"STARTED\"] },\n"
+ " 0,\n"
+ " {\n"
+ " $cond: [{$or: [{ $eq: [\"$event.status\","
+ " \"COMMITTED\"] },{ $eq: [\"$event.status\", \"REVIEWING\"] }]}, 1, \n"
+ " {$cond: [{ $eq: [\"$event.status\","
+ " \"APPROVED\"] }, 2, 3]}\n"
+ " ],\n"
+ " },\n"
+ " ]\n"
+ " }\n"
+ " \n"
+ " }\n"
+ " },",
" {\n"
+ " $sort: {\n"
+ " statusIndex: 1,\n"
+ " actualEndDate: -1,\n"
+ " planStartDate: -1\n"
+ " }\n"
+ " },",
" {\n" + " $skip: ?1\n" + " },",
" {\n" + " $limit: ?2\n" + " },"
})
List<Event> findByHostIdOrderCustom(String hostId, Integer skip, Integer limit);
关于聚合:
文档进入多阶段管道,将文档转换为聚合结果。例如:
在这个例子中:
db.orders.aggregate([
{ $match: { status: "A" } },
{ $group: { _id: "$cust_id", total: { $sum: "$amount" } } }
])
第一阶段:$match阶段按status字段过滤文档,并将status等于"A"的文档传递到下一阶段。
第二阶段:$group阶段按cust_id字段将文档分组,以计算每个唯一值cust_id的金额总和。
最基本的管道阶段提供_过滤器_,其操作类似于查询和修改输出文档格式的_文档转换_。
使用mongoTemplate:
@Override
public Long deleteReplyById(String commentId, String replyId, String userId) {
Query query =
Query.query(Criteria.where("replies.id").is(replyId))
.addCriteria(Criteria.where("id").is(commentId));
Update update =
new Update().set("replies.$.deleteDate", new Date()).set("replies.$.deleteBy", userId);
UpdateResult result = mongoTemplate.updateFirst(query, update, EventComment.class);
return result.getModifiedCount();
}
其他的一些数据库操作:
User user = new User();
user.setId("12345");
user.setName("admin");
user.setAddress("测试");
Query query = Query.query(Criteria.where("_id").is("5d1312aeb1829c279c6c256b"));
Update update = Update.update("name","zs");
// 更新一条数据
mongoTemplate.updateFirst(query,update, User.class);
mongoTemplate.updateFirst(query,update, "mongodb_user");
mongoTemplate.updateFirst(query,update, User.class,"mongodb_user");
// 更新多条数据
mongoTemplate.updateMulti(query,update, User.class);
mongoTemplate.updateMulti(query,update,"mongodb_user");
mongoTemplate.updateMulti(query,update, User.class,"mongodb_user");
// 更新数据,如果数据不存在就新增
mongoTemplate.upsert(query,update, User.class);
mongoTemplate.upsert(query,update,"mongodb_user");
mongoTemplate.upsert(query,update, User.class,"mongodb_user");