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

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; package com.red.circle.other.app.scheduler;
import com.red.circle.component.redis.annotation.TaskCacheLock; 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.framework.mybatis.constant.PageConstant;
import com.red.circle.other.infra.database.cache.service.other.DynamicCacheService; import com.red.circle.other.infra.database.cache.service.other.DynamicCacheService;
import com.red.circle.other.infra.database.rds.entity.dynamic.DynamicComment; 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.List;
import java.util.Objects; import java.util.Objects;
import java.util.Optional; import java.util.Optional;
import java.util.concurrent.TimeUnit;
import lombok.RequiredArgsConstructor; import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j; import lombok.extern.slf4j.Slf4j;
import org.springframework.scheduling.annotation.Scheduled; import org.springframework.scheduling.annotation.Scheduled;
@ -18,7 +16,7 @@ import org.springframework.stereotype.Component;
/** /**
* 评论热度分数更新定时任务. * 评论热度分数更新定时任务.
* 每10分钟执行一次更新最近7天的评论热度分数 * 每10分钟执行一次更新最近7天的评论热度分数
*/ */
@Slf4j @Slf4j
@Component @Component
@ -46,22 +44,22 @@ public class DynamicCommentHotScoreTask {
while (hasMore) { while (hasMore) {
// 分批查询每次1000条 // 分批查询每次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; hasMore = false;
break; break;
} }
// 批量更新热度分数 // 批量更新热度分数
for (DynamicComment comment : comments) { for (DynamicComment rootComment : rootComments) {
updateCommentHotScore(comment); updateCommentHotScore(rootComment);
totalUpdated++; totalUpdated++;
} }
// 准备下一批 // 准备下一批
lastId = comments.get(comments.size() - 1).getId(); lastId = rootComments.get(rootComments.size() - 1).getId();
hasMore = comments.size() >= 1000; hasMore = rootComments.size() >= 1000;
} }
long costTime = System.currentTimeMillis() - startTime; 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() return dynamicCommentService.query()
.isNull(DynamicComment::getRootCommentId) .isNull(DynamicComment::getRootCommentId)
.ge(DynamicComment::getCreateTime, new java.sql.Timestamp(since)) .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 { try {
// 获取点赞数 // 1. 获取根评论自身的点赞数
Long likeCount = Optional.ofNullable( Long rootLikeCount = Optional.ofNullable(
dynamicCacheService.getCommentLikeQuantity(comment.getDynamicContentId(), comment.getId()) dynamicCacheService.getCommentLikeQuantity(rootComment.getDynamicContentId(), rootComment.getId())
).orElse(0L); ).orElse(0L);
// 计算热度分数 // 2. 查询该根评论下的所有子评论
double hotScore = calculateHotScore(comment, likeCount); 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() dynamicCommentService.update()
.set(DynamicComment::getHotScore, hotScore) .set(DynamicComment::getHotScore, hotScore)
.eq(DynamicComment::getId, comment.getId()) .eq(DynamicComment::getId, rootComment.getId())
.last(PageConstant.LIMIT_ONE) .last(PageConstant.LIMIT_ONE)
.execute(); .execute();
if (totalChildLikes > 0) {
log.debug("更新评论热度 - 根评论ID:{}, 根评论点赞:{}, 子评论点赞:{}, 总点赞:{}, 热度分数:{}",
rootComment.getId(), rootLikeCount, totalChildLikes, totalLikeCount, hotScore);
}
} catch (Exception e) { } 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 currentTime = System.currentTimeMillis();
long ageMillis = currentTime - comment.getCreateTime().getTime(); long ageMillis = currentTime - comment.getCreateTime().getTime();
double ageHours = Math.max(ageMillis / (1000.0 * 60 * 60), 0.1); 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);
} }
} }