Files
web_hghl_server/app/service/configser/rankstat.go
T
2026-10-26 16:28:14 +08:00

92 lines
2.8 KiB
Go

package configser
import (
"context"
"time"
"videoweb/pub/common/log"
"videoweb/pub/models/videofavoritemod"
"videoweb/pub/models/videoinformationmod"
"go.mongodb.org/mongo-driver/bson"
"go.mongodb.org/mongo-driver/mongo"
)
// favoriteCountResult 收藏聚合结果
type favoriteCountResult struct {
Id int64 `bson:"_id"`
Count int64 `bson:"count"`
}
// UpdateAllFavoriteDataCount 统计视频收藏量并写回DB
func UpdateAllFavoriteDataCount() {
updateVideoFavoriteDataCount(context.Background())
}
// buildFavoritePipeline 构建按时间窗口统计收藏量的聚合 pipeline
// contentIdField: favorite表中内容ID字段名(如 videoId)
// since: 统计起始时间,零值表示统计全量
func buildFavoritePipeline(contentIdField string, since time.Time) []bson.M {
matchStage := bson.M{}
if !since.IsZero() {
matchStage["createdAt"] = bson.M{"$gte": since}
}
pipeline := []bson.M{}
if len(matchStage) > 0 {
pipeline = append(pipeline, bson.M{"$match": matchStage})
}
pipeline = append(pipeline,
bson.M{"$group": bson.M{
"_id": "$" + contentIdField,
"count": bson.M{"$sum": 1},
}},
)
return pipeline
}
// updateVideoFavoriteDataCount 统计视频收藏量,更新 Likes/WeekLikes/MonthLikes/YearLikes
func updateVideoFavoriteDataCount(ctx context.Context) {
now := time.Now()
type period struct {
field string
since time.Time
}
periods := []period{
{videoinformationmod.FN.VideoInformation.Real.Likes, time.Time{}},
{videoinformationmod.FN.VideoInformation.Real.WeekLikes, now.AddDate(0, 0, -7)},
{videoinformationmod.FN.VideoInformation.Real.MonthLikes, now.AddDate(0, 0, -30)},
{videoinformationmod.FN.VideoInformation.Real.YearLikes, now.AddDate(0, 0, -365)},
}
idField := videofavoritemod.FN.VideoFavorite.VideoID
for _, p := range periods {
var results []favoriteCountResult
pipeline := buildFavoritePipeline(idField, p.since)
if serr := videofavoritemod.AggregateVideoFavorite(ctx, &results, pipeline); serr != nil {
log.Warn("updateVideoFavoriteDataCount aggregate failed", log.Any("field", p.field))
continue
}
if len(results) == 0 {
continue
}
writes := make([]mongo.WriteModel, 0, len(results))
for _, r := range results {
writes = append(writes, mongo.NewUpdateOneModel().
SetFilter(bson.M{videoinformationmod.FN.VideoInformation.Id: r.Id}).
SetUpdate(bson.M{"$set": bson.M{p.field: r.Count}}),
)
}
if _, serr := videoinformationmod.BulkWriteVideoInformation(ctx, writes); serr != nil {
log.Warn("updateVideoFavoriteDataCount bulk update failed", log.Any("field", p.field))
}
}
}
// RankPeriod 排行榜时间维度
type RankPeriod int
const (
RankPeriodTotal RankPeriod = 0 // 总榜
RankPeriodWeek RankPeriod = 1 // 周榜
RankPeriodMonth RankPeriod = 2 // 月榜
RankPeriodYear RankPeriod = 3 // 年榜
)