SpringDataMongoDB常用代码集
2022-01-21 本文已影响0人
AC编程
一、判断字段是否存在
List<AggregationOperation> operations = new ArrayList<>();
operations.add(Aggregation.match(Criteria.where("rootId").exists(true)));
二、等于值 & 不等于
2.1 等于
List<AggregationOperation> operations = new ArrayList<>();
operations.add(Aggregation.match(Criteria.where("rootId").is("ID值")));
2.2 不等于
query.addCriteria(Criteria.where("rootId").ne("ID值"));
三、等于null
List<AggregationOperation> operations = new ArrayList<>();
operations.add(Aggregation.match(Criteria.where("rootId").is(null)));
四、or
List<AggregationOperation> operations = new ArrayList<>();
operations.add(Aggregation.match(new Criteria().orOperator(Criteria.where("rootId").exists(true),
Criteria.where("rootId").is(null))));
五、ObjectId类型转String
commentDTO.getId().toHexString()
六、String转ObjectId类型
String typeId = "ID值";
ObjectId id = new ObjectId(typeId);
七、模糊查询
7.1 全模糊查询
方式一
/**
* query 模糊查询
*
* @param field 字段
* @param value 模糊匹配目标值
* @param regex 添加自定义匹配规则
* @return
*/
public static Criteria queryLike(String field, Object value, String regex) {
Pattern compile = null;
if (StringUtils.isNotBlank(regex)) {
compile = Pattern.compile(regex);
} else {
compile = Pattern.compile("^.*" + value + ".*$", Pattern.CASE_INSENSITIVE);
}
return Criteria.where(field).regex(compile);
}
方式二
/**
* 聚合模糊查询
*
* @param field
* @param value
* @param regex 模糊匹配正则表达式
* @return
*/
public static MatchOperation matchLike(String field, Object value, String regex) {
Pattern compile = null;
if (StringUtils.isNotBlank(regex)) {
compile = Pattern.compile(regex);
} else {
compile = Pattern.compile("^.*" + value + ".*$", Pattern.CASE_INSENSITIVE);
}
return Aggregation.match(Criteria.where(field).regex(compile));
}
7.2 前缀模糊
public static MatchOperation matchStartWith(String field, String value) {
Pattern compile = Pattern.compile("^" + Pattern.quote(value), Pattern.CASE_INSENSITIVE);
return Aggregation.match(Criteria.where(field).regex(compile));
}
取非
public static MatchOperation matchNotStartWith(String field, String value) {
Pattern compile = Pattern.compile("^" + Pattern.quote(value), Pattern.CASE_INSENSITIVE);
return Aggregation.match(Criteria.where(field).not().regex(compile));
}
八、局部修改
只修改传的字段的值,其他字段保持不变
8.1 局部修改一个字段
Query query = Query.query(Criteria.where("_id").is(item.getId()));
Update update = new Update();
update.set("images", newImages);
mongoTemplate.updateFirst(query, update, OssActivity.class);
8.2 updateFirst
/**
* 1、局部修改
* 2、updateFirst只会修改查询结果的第一条记录
* 3、id=612f1f2727296f7a36a56406的记录修改成功(第一条记录)
* 4、id=612f1f2a27296f7a36a56417的记录没有被修改(第二条记录)
*/
private void updateFirstTest(){
Query query = Query.query(Criteria.where("_id").in("612f1f2727296f7a36a56406","612f1f2a27296f7a36a56417"));
Update update = new Update();
update.set("visit_nums", 30);
update.set("read_nums", 40);
mongoTemplate.updateFirst(query, update, DynamicDetailEntity.class);
}
8.3 updateMulti
/**
* 1、局部修改
* 2、updateMulti会修改查询结果的所有记录
* 3、id=612f1f2727296f7a36a56406的记录修改成功(第一条记录)
* 4、id=612f1f2a27296f7a36a56417的记录修改成功(第二条记录)
*/
private void updateMultiTest(){
Query query = Query.query(Criteria.where("_id").in("612f1f2727296f7a36a56406","612f1f2a27296f7a36a56417"));
Update update = new Update();
update.set("visit_nums", 30);
update.set("read_nums", 40);
mongoTemplate.updateMulti(query, update, DynamicDetailEntity.class);
}
九、自增
9.1 常规方式
/**
* 自增
* @param id
* @param field
* @param number
*/
public void incr(String id, String field, int number) {
Query query = new Query(Criteria.where("_id").is(id));
Update update = new Update();
update.inc(field, number);
UpdateResult updateResult = mongoTemplate.updateFirst(query, update, DynamicGroupEntity.class);
}
9.2 通用方式
repositoryOps.incr(likeVO.getDynamicId(), "like_nums", 1, DynamicDetailEntity.class);
public <T> void incr(String id, String filed, int number, Class<T> tClass) {
Query query = new Query(Criteria.where("_id").is(id));
Update update = new Update();
update.inc(filed, number);
UpdateResult updateResult = mongoTemplate.updateFirst(query,
update, tClass);
}
十、not in & in
11.1 not in
public static MatchOperation nor(String field, Object... value) {
return Aggregation.match(new Criteria().norOperator(where(field).in(value)));
}
11.2 in
Query query = new Query();
query.addCriteria(Criteria.where("_id").in(listIds));
List<DynamicDetailEntity> list = mongoTemplate.find(query, DynamicDetailEntity.class);
List<AggregationOperation> operations = new ArrayList<>();
operations.add(Aggregation.match(Criteria.where("memberId").in(listIds)));
十一、对比
public enum OpEnum {
//GT:大于,LT:小于,GTE:大于等于,LTE:小于等于,NE:不等于
GT,
LT,
GTE,
LTE,
NE;
public boolean eq(CacheMode cacheMode) {
return cacheMode != null && this.name().equals(cacheMode.name());
}
}
方式一
public static MatchOperation op(String field, Integer data, OpEnum op) {
if (null == op) {
return null;
}
Criteria criteria = null;
switch (op) {
case GT:
criteria = Criteria.where(field).exists(Boolean.TRUE).andOperator(Criteria.where(field).gt(data));
break;
case LT:
criteria = Criteria.where(field).exists(Boolean.TRUE).andOperator(Criteria.where(field).lt(data));
break;
case GTE:
criteria = Criteria.where(field).exists(Boolean.TRUE).andOperator(Criteria.where(field).gte(data));
break;
case LTE:
criteria = Criteria.where(field).exists(Boolean.TRUE).andOperator(Criteria.where(field).lte(data));
break;
case NE:
criteria = Criteria.where(field).exists(Boolean.TRUE).andOperator(Criteria.where(field).ne(data));
break;
}
return Aggregation.match(criteria);
}
方式二
public static Criteria queryOp(String field, Integer data, OpEnum op) {
if (null == op) {
return null;
}
Criteria criteria = null;
switch (op) {
case GT:
criteria = Criteria.where(field).exists(Boolean.TRUE).andOperator(Criteria.where(field).gt(data));
break;
case LT:
criteria = Criteria.where(field).exists(Boolean.TRUE).andOperator(Criteria.where(field).lt(data));
break;
case GTE:
criteria = Criteria.where(field).exists(Boolean.TRUE).andOperator(Criteria.where(field).gte(data));
break;
case LTE:
criteria = Criteria.where(field).exists(Boolean.TRUE).andOperator(Criteria.where(field).lte(data));
break;
case NE:
criteria = Criteria.where(field).exists(Boolean.TRUE).andOperator(Criteria.where(field).ne(data));
break;
}
return criteria;
}
十二、范围查找
12.1 数字类型范围查找
public static MatchOperation range(String field, List<Long> data) {
if(null == data.get(1) || 0l == data.get(1).longValue()) {
return Aggregation.match(
Criteria.where(field).exists(Boolean.TRUE)
.andOperator(
Criteria.where(field).gte(data.get(0))
));
}
return Aggregation.match(
Criteria.where(field).exists(Boolean.TRUE)
.andOperator(
Criteria.where(field).gte(data.get(0)),
Criteria.where(field).lte(data.get(1))
));
}
12.2 时间范围查找
public static MatchOperation rangeTime(String field, List<String> data) {
return Aggregation.match(Criteria.where(field).exists(Boolean.TRUE)
.andOperator(
Criteria.where(field).gte(strToDateLong(data.get(0))),
Criteria.where(field).lte(strToDateLong(data.get(1)))
));
}
public static Date strToDateLong(String strDate) {
Date strtodate = null;
try {
SimpleDateFormat formatter = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
strtodate = formatter.parse(strDate);
} catch (ParseException e) {
e.printStackTrace();
}
return strtodate;
}
十三、case when 自定义排序
/**
* 动态评论排序显示
* 1、以当前登录用户(看评论的人)为中心,和“我”相关的评论显示在前面(我发表的评论;别人评论有@我的;我评论了别人的一级评论)
* 2、再显示动态作者自己写的评论
* 3、最后显示其他人的评论
* 4、如果条件相同的情况下,再按点赞数、权重、时间倒序
* @param vo
* @param commentPageVO
* @param memberId
* @return
*/
@Override
public IPage<CommentEntityDTO> selectByPage(PagerVO vo, CommentPageVO commentPageVO, Long memberId) {
PageModel sort = MongoUtils.sort(vo);
sort.getOrder().add("likeNums");
List<AggregationOperation> operations = new ArrayList<>();
if (StringUtils.isNotBlank(commentPageVO.getDynamicId())) {
operations.add(MongoUtils.match("dynamicId", commentPageVO.getDynamicId()));
} else {
throw new Exception(ResultCode.DATA_EMPTY, I18nUtils.message("content.comm.null"));
}
if (null != commentPageVO.getSkippedCommentIds() && commentPageVO.getSkippedCommentIds().length > 0) {
operations.add(MongoUtils.nor("_id", commentPageVO.getSkippedCommentIds()));
}
if (StringUtils.isNotBlank(commentPageVO.getReplyId())) {
operations.add(Aggregation.match(Criteria.where("rootId").is(commentPageVO.getReplyId())));
} else {
operations.add(Aggregation.match(new Criteria().orOperator(Criteria.where("rootId").exists(Boolean.FALSE),
Criteria.where("rootId").is(null))));
sort.getOrder().add("commentWeight");
}
DynamicDetailDTO dynamicDetailDTO = dynamicAppService.getOne(commentPageVO.getDynamicId());
//看的人是发表评论的给5 at看的给3 文章作者给排序值为1, 默认给0,再排序
Switch.CaseOperator cond1 = Switch.CaseOperator.when(ComparisonOperators.Eq.valueOf("memberId").equalToValue(memberId)).then(5);
Switch.CaseOperator cond2 = Switch.CaseOperator.when(ComparisonOperators.Eq.valueOf("atMember.memberId").equalToValue(memberId)).then(3);
Switch.CaseOperator cond3 = Switch.CaseOperator.when(ComparisonOperators.Eq.valueOf("memberId").equalToValue(dynamicDetailDTO.getMemberId())).then(1);
//有实体字段的先设置一下排序
operations.add(MongoUtils.sort(Sort.Direction.DESC, sort.getOrder(), Boolean.TRUE));
long totalCount = repositoryOps.getTotalCount(operations, new CommentEntity().getTableName(), CommentEntity.class);
operations.add(Aggregation.project(CommentEntity.class).and(ConditionalOperators.switchCases(cond1, cond2, cond3).defaultTo(0)).as("customSort"));
//虚拟字段排序要放在project后面才有效果
List orderList = new ArrayList();
orderList.add("customSort");
operations.add(MongoUtils.sort(Sort.Direction.DESC, orderList, Boolean.TRUE));
Aggregation aggregation = Aggregation.newAggregation(operations);
AggregationResults<CommentEntity> results = mongoTemplate.aggregate(aggregation, new CommentEntity().getTableName(), CommentEntity.class);
List<CommentEntityDTO> commentEntityDTOS = new ArrayList<>();
results.getMappedResults().forEach(d -> {
if (d.getDeleted()) {
d.setContent(I18nUtils.message("content.comment.removed"));
}
if (d.getDeleted() || d.getIsAnonymous().equals(1)) {
d.setCommentMember(MemberInfos.builder()
.memberNickName(I18nUtils.message("default.member"))
.build());
}
CommentEntityDTO dto = CommentConvert.instance.toDTO(d);
//一级时处理默认展开的评论
if (StringUtils.isBlank(commentPageVO.getReplyId())) {
List<CommentEntityDTO> child = getChildComment(commentPageVO.getDynamicId(),d.getId().toHexString(), memberId);
dto.setChildComment(child);
}
commentEntityDTOS.add(dto);
});
if (null != memberId) {
setLike(commentEntityDTOS, memberId);
}
IPage<CommentEntityDTO> page = MongoUtils.getPage(sort.getPageRequest().getPageNumber(), sort.getLimit(), totalCount, commentEntityDTOS);
return page;
}
/**
* 需要默认展开的评论
* @param dynamicId
* @param replyId
* @param memberId
* @return
*/
private List<CommentEntityDTO> getChildComment(String dynamicId, String replyId,Long memberId) {
List<AggregationOperation> operations = new ArrayList<>();
operations.add(MongoUtils.match("dynamicId", dynamicId));
operations.add(Aggregation.match(Criteria.where("rootId").is(replyId)));
operations.add(Aggregation.match(new Criteria().orOperator(Criteria.where("memberId").is(memberId),
Criteria.where("atMember.memberId").is(memberId),
Criteria.where("commentMember.memberId").is(memberId)
)));
Aggregation aggregation = Aggregation.newAggregation(operations);
AggregationResults<CommentEntity> results = mongoTemplate.aggregate(aggregation, new CommentEntity().getTableName(), CommentEntity.class);
List<CommentEntityDTO> commentEntityDTOS = new ArrayList<>();
results.getMappedResults().forEach(d -> {
CommentEntityDTO dto = CommentConvert.instance.toDTO(d);
commentEntityDTOS.add(dto);
});
return commentEntityDTOS;
}
十四、删除
14.1 物理删除
Query query = new Query();
query.addCriteria(Criteria.where("member_id").is(memberId));
query.addCriteria(Criteria.where("dynamic_id").is(detailDTO.getId()));
mongoTemplate.remove(query, DynamicLikeLog.class).getDeletedCount() > 0;
14.2 逻辑删除
Query query = Query.query(Criteria.where("_id").is(new ObjectId(id)));
Update update = new Update();
update.set("deleted", true);
UpdateResult deleted = mongoTemplate.updateFirst(query, update, DynamicDetailEntity.class);
boolean result = deleted.getModifiedCount() > 0;
十五、count
15.1 判断是否存在
Query query = new Query();
query.addCriteria(Criteria.where("member_id").is(memberId));
query.addCriteria(Criteria.where("dynamic_id").is(dynamicId));
return mongoTemplate.count(query, DynamicLikeLog.class) > 0;
15.2 按时间统计
long releaseDyCount = mongoTemplate.count(
new Query()
.addCriteria(Criteria.where("memberId").is(memberId))
.addCriteria(Criteria.where("deleted").is(Boolean.FALSE))
.addCriteria(Criteria.where("createTime").exists(Boolean.TRUE)
.andOperator(
Criteria.where("createTime").gte(DateUtil.beginOfDay(date)),
Criteria.where("createTime").lte(DateUtil.endOfDay(date))
))
, DynamicDetailEntity.class);
十六、获取用户动态平均点赞数
public Integer calcLikeAvg(Long memberId) {
Aggregation aggregation = Aggregation.newAggregation(
Aggregation.match(Criteria.where("memberId").is(memberId).and("deleted").is(false)),
Aggregation.group("memberId")
.count().as("count")
.sum("like_nums").as("sum")
.avg("like_nums").as("avg"),
Aggregation.project("count", "sum", "avg")
);
AggregationResults<DynamicLikeAvg> result = mongoTemplate.aggregate(aggregation, "dynamic", DynamicLikeAvg.class);
List<DynamicLikeAvg> list = result.getMappedResults();
if (CollectionUtils.isNotEmpty(list)) {
DynamicLikeAvg likeAvg = list.get(0);
Double avg = likeAvg.getAvg();
//取整(抹零)
return NumberUtil.round(avg);
}
return 0;
}
@Data
public class DynamicLikeAvg {
/**
* 记录数
*/
private Integer count;
/**
* 总点赞数
*/
private Integer sum;
/**
* 平均点赞数
*/
private Double avg;
}
十七、排序
17.1 方式一
Query query = new Query();
query.addCriteria(MongoUtils.where("deleted").is(false));
query.addCriteria(MongoUtils.where("type").is(type));
query.with(Sort.by(Sort.Order.desc("ranking"))).limit(count);
List<DynamicDetailEntity> dyList = mongoTemplate.find(query, DynamicDetailEntity.class);
17.2 方式二
List<AggregationOperation> operations = new ArrayList<>();
operations.add(Aggregation.match(Criteria.where("deleted").is(false)));
operations.add(Aggregation.match(Criteria.where("type").is(type)));
operations.add(Aggregation.sort(Sort.by(Sort.Order.desc("ranking"))));
operations.add(Aggregation.limit(count));
Aggregation aggregation = Aggregation.newAggregation(operations);
AggregationResults<DynamicDetailEntity> results = mongoTemplate.aggregate(aggregation, "dynamic", DynamicDetailEntity.class);
十八、修改子文档数组里面的对象数据
文档结构:
{
"_id": {
"$oid": "61af2ea42ea687423806e8df"
},
"member_id": "184498262835201",
"questions": [{
"question": "测试",
"answers": ["https://test-public.oss-cn-shenzhen.aliyuncs.com/game/184498262835201/Image/2021/12/08/jfmdinanclmjbin_0.jpg", "https://test-public.oss-cn-shenzhen.aliyuncs.com/game/184498262835201/Image/2021/12/08/omfmobeojadhmmh_1.jpg", "https://test-public.oss-cn-shenzhen.aliyuncs.com/game/184498262835201/Image/2021/12/08/ogjfaeeafdbemhi_2.jpg", "https://test-public.oss-cn-shenzhen.aliyuncs.com/game/184498262835201/Image/2021/12/08/bdknkckdndlendc_3.jpg"],
"true_answer": 1,
"answer_type": 2
}, {
"question": "9",
"answers": ["选我", "1", "2", "3"],
"true_answer": 0,
"answer_type": 1
}, {
"question": "8",
"answers": ["选我", "1", "2", "3"],
"true_answer": 0,
"answer_type": 1
}],
"status": 0,
"member_type": "",
"create_time": {
"$numberLong": "1638870667273"
},
"modify_time": {
"$numberLong": "1638948579214"
}
}
目标:修改questions.answers里的数据
Query queryUpdate = Query.query(new Criteria().andOperator(Criteria.where("_id").is(item.getId()),
Criteria.where("questions").elemMatch(Criteria.where("question").is(question.getQuestion()))));
Update update = new Update();
update.set("questions.$.answers", newAnswers);
mongoTemplate.updateFirst(queryUpdate, update, OssGameQuestion.class);