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);
上一篇下一篇

猜你喜欢

热点阅读