评论热度分数更新定时任务 修改

This commit is contained in:
tianfeng 2026-02-04 18:16:40 +08:00
parent 15b28fe6b5
commit 0c62d14e2b

View File

@ -1,7 +1,6 @@
package com.red.circle.other.app.scheduler;
import com.red.circle.component.redis.annotation.TaskCacheLock;
import com.red.circle.component.redis.service.RedisService;
import com.red.circle.framework.mybatis.constant.PageConstant;
import com.red.circle.other.infra.database.cache.service.other.DynamicCacheService;
import com.red.circle.other.infra.database.rds.entity.dynamic.DynamicComment;
@ -10,7 +9,6 @@ import com.red.circle.tool.core.collection.CollectionUtils;
import java.util.List;
import java.util.Objects;
import java.util.Optional;
import java.util.concurrent.TimeUnit;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.scheduling.annotation.Scheduled;
@ -18,7 +16,7 @@ import org.springframework.stereotype.Component;
/**
* 评论热度分数更新定时任务.
* 每10分钟执行一次更新最近7天的评论热度分数
* 每10分钟执行一次更新最近7天的评论热度分数
*/
@Slf4j
@Component
@ -46,22 +44,22 @@ public class DynamicCommentHotScoreTask {
while (hasMore) {
// 分批查询每次1000条
List<DynamicComment> comments = queryRecentComments(sevenDaysAgo, lastId, 1000);
List<DynamicComment> rootComments = queryRecentRootComments(sevenDaysAgo, lastId, 1000);
if (CollectionUtils.isEmpty(comments)) {
if (CollectionUtils.isEmpty(rootComments)) {
hasMore = false;
break;
}
// 批量更新热度分数
for (DynamicComment comment : comments) {
updateCommentHotScore(comment);
for (DynamicComment rootComment : rootComments) {
updateCommentHotScore(rootComment);
totalUpdated++;
}
// 准备下一批
lastId = comments.get(comments.size() - 1).getId();
hasMore = comments.size() >= 1000;
lastId = rootComments.get(rootComments.size() - 1).getId();
hasMore = rootComments.size() >= 1000;
}
long costTime = System.currentTimeMillis() - startTime;
@ -73,9 +71,9 @@ public class DynamicCommentHotScoreTask {
}
/**
* 查询最近的根评论
* 查询最近的根评论root_comment_id null
*/
private List<DynamicComment> queryRecentComments(long since, Long lastId, int limit) {
private List<DynamicComment> queryRecentRootComments(long since, Long lastId, int limit) {
return dynamicCommentService.query()
.isNull(DynamicComment::getRootCommentId)
.ge(DynamicComment::getCreateTime, new java.sql.Timestamp(since))
@ -86,40 +84,64 @@ public class DynamicCommentHotScoreTask {
}
/**
* 更新单条评论的热度分数
* 更新单条评论的热度分数
*/
private void updateCommentHotScore(DynamicComment comment) {
private void updateCommentHotScore(DynamicComment rootComment) {
try {
// 获取点赞数
Long likeCount = Optional.ofNullable(
dynamicCacheService.getCommentLikeQuantity(comment.getDynamicContentId(), comment.getId())
// 1. 获取根评论自身的点赞数
Long rootLikeCount = Optional.ofNullable(
dynamicCacheService.getCommentLikeQuantity(rootComment.getDynamicContentId(), rootComment.getId())
).orElse(0L);
// 计算热度分数
double hotScore = calculateHotScore(comment, likeCount);
// 2. 查询该根评论下的所有子评论
List<DynamicComment> childComments = dynamicCommentService.query()
.eq(DynamicComment::getRootCommentId, rootComment.getId())
.list();
// 更新到数据库
// 3. 汇总所有子评论的点赞数
long totalChildLikes = 0L;
if (CollectionUtils.isNotEmpty(childComments)) {
for (DynamicComment childComment : childComments) {
Long childLikeCount = Optional.ofNullable(
dynamicCacheService.getCommentLikeQuantity(childComment.getDynamicContentId(), childComment.getId())
).orElse(0L);
totalChildLikes += childLikeCount;
}
}
// 4. 总点赞数 = 根评论点赞数 + 所有子评论点赞数
long totalLikeCount = rootLikeCount + totalChildLikes;
// 5. 计算热度分数
double hotScore = calculateHotScore(rootComment, totalLikeCount);
// 6. 更新到数据库
dynamicCommentService.update()
.set(DynamicComment::getHotScore, hotScore)
.eq(DynamicComment::getId, comment.getId())
.eq(DynamicComment::getId, rootComment.getId())
.last(PageConstant.LIMIT_ONE)
.execute();
if (totalChildLikes > 0) {
log.debug("更新评论热度 - 根评论ID:{}, 根评论点赞:{}, 子评论点赞:{}, 总点赞:{}, 热度分数:{}",
rootComment.getId(), rootLikeCount, totalChildLikes, totalLikeCount, hotScore);
}
} catch (Exception e) {
log.error("更新评论热度分数失败commentId={}", comment.getId(), e);
log.error("更新评论热度分数失败,rootCommentId={}", rootComment.getId(), e);
}
}
/**
* 计算热度分数
* 公式: 点赞数 / (时间差小时数 + 2)^1.5
* 公式: 点赞数 / (时间差小时数 + 2)^1.5
*/
private double calculateHotScore(DynamicComment comment, Long likeCount) {
private double calculateHotScore(DynamicComment comment, Long totalLikeCount) {
long currentTime = System.currentTimeMillis();
long ageMillis = currentTime - comment.getCreateTime().getTime();
double ageHours = Math.max(ageMillis / (1000.0 * 60 * 60), 0.1);
return likeCount / Math.pow(ageHours + 2, 1.5);
return totalLikeCount / Math.pow(ageHours + 2, 1.5);
}
}