@Data
@Document("db_comment")
public class DbComment {
@Id
private ObjectId id;
// 创建时间
private LocalDateTime createdAt;
// 更新时间
private LocalDateTime updatedAt;
// 删除标识
private Boolean deleted;
// 删除时间
private LocalDateTime deletedAt;
// 父评论id
private ObjectId parentId;
// 该评论的用户id
private ObjectId userId;
// 评论内容
private String content;
// 点赞的数量
private Integer likeCount;
// 回复的数量
private Integer replyCount;
// 评论类型 作品评论/文章评论
private CommentTypeEnum resourceType;
// 评论目标id 作品/文章
private ObjectId resourceId;
// 资源作者
private ObjectId resourceAuthorId;
// 是否为作者评论
private Boolean isAuthor;
// 回复用户id
private ObjectId replyToUserId;
}
这是我的评论表结构,在分页查询时,需要查询父级评论并查询文章作者的二级评论。当cid存在时,又需要将该条评论在第一页置顶,如果cid为二级评论时需要将父评论置顶,并将该评论展示出来,我可以一次将该文章下的所有评论查询出来,在代码中遍历分页,可这种操作非常占用内存效率也低。我又不希望关联查询,mongo的复杂查询很麻烦。这个cid存在时,我可以单独的对该条评论做两次查询,然后组装成commentVo 加到commentVos顶部 可这份数据又会造成多次的user信息以及是否喜欢信息的查询,还要处理Cursor以及Count结果,当c我应该怎么实现这份功能,下面的代码我并没有写当cid存在时将该条评论置顶的业务逻辑,因为很困惑!
/**
* @param commentListQuery
* @return
*/
@Override
public R<CommentResultVo> getList(CommentListQuery commentListQuery) {
ObjectId cid = commentListQuery.getCid();
ObjectId resourceId = commentListQuery.getResourceId();
Integer resourceType = commentListQuery.getResourceType();
Integer cursor = commentListQuery.getCursor();
Integer count = commentListQuery.getCount();
ObjectId userId = StpUtil.isLogin()?new ObjectId(StpUtil.getLoginIdAsString()):null;
Criteria criteria = where(DbComment.Fields.resourceId).is(resourceId).and(DbComment.Fields.resourceType).is(resourceType).and(DbComment.Fields.parentId).isNull();
long total = commentMapper.selectCount(query(criteria));
// 获取一级评论总数
Query query = query(where(DbComment.Fields.resourceId).is(resourceId).and(DbComment.Fields.resourceType).is(resourceType).and(DbComment.Fields.parentId).isNull());
query.skip(cursor);
query.limit(count);
query.with(Sort.by(Sort.Direction.DESC, BaseEntity.Fields.createdAt));
List<DbComment> dbComments = commentMapper.selectList(query);
List<ObjectId> commentIds = ConvertUtils.resultToList(dbComments, DbComment::getId);
List<ObjectId> userIds = ConvertUtils.resultToList(dbComments, DbComment::getUserId);
List<DbUser> dbUsers = userMapper.selectByIds(userIds);
Map<ObjectId, DbUser> userMap = ConvertUtils.listToMap(dbUsers, DbUser::getId);
// 点赞的评论ids
List<ObjectId> likeCommentIds = new ArrayList<>();
if (Objects.nonNull(userId)) {
List<DbLike> dbLikes = likeMapper.selectLikes(userId, commentIds, ResourceTypeEnum.COMMENT);
for (DbLike dbLike : dbLikes) {
likeCommentIds.add(dbLike.getId());
}
}
List<CommentVo> commentVos;
try(ExecutorService executor = Executors.newVirtualThreadPerTaskExecutor()){
List<CompletableFuture<CommentVo>> futures = dbComments.stream()
.map(dbComment -> CompletableFuture.supplyAsync(() -> {
CommentVo commentVo = new CommentVo();
commentVo.setId(dbComment.getId());
commentVo.setUserId(dbComment.getUserId());
if (Objects.nonNull(dbComment.getUserId())){
DbUser user = userMap.get(dbComment.getUserId());
if (Objects.nonNull(user)){
UserVo userVo = UserJson.toVo(user);
commentVo.setUser(userVo);
}
}
commentVo.setContent(dbComment.getContent());
commentVo.setReplyCount(dbComment.getReplyCount());
commentVo.setLikeCount(dbComment.getLikeCount());
commentVo.setLike(likeCommentIds.contains(dbComment.getId()));
commentVo.setAuthor(dbComment.getIsAuthor());
commentVo.setCreatedAt(dbComment.getCreatedAt());
commentVo.setUpdatedAt(dbComment.getUpdatedAt());
// 查询每个父评论的前三条子评论
Query childQuery = query(where(DbComment.Fields.parentId).is(dbComment.getId()).and(DbComment.Fields.isAuthor).is(true));
childQuery.with(Sort.by(Sort.Direction.DESC, BaseEntity.Fields.createdAt));
childQuery.limit(1);
commentVo.setSubComment(getSubComments(childQuery, userId));
return commentVo;
}, executor))
.toList();
commentVos = futures.stream()
.map(CompletableFuture::join)
.collect(Collectors.toList());
}catch (Exception e){
commentVos= Collections.emptyList();
}
CommentResultVo pagerVo = new CommentResultVo();
pagerVo.setCursor(cursor + dbComments.size());
pagerVo.setCount(commentVos.size());
pagerVo.setTotal(total);
pagerVo.setComments(commentVos);
pagerVo.setHasMore(cursor + commentVos.size() < total);
return R.data(pagerVo);
}