92 lines
2.8 KiB
Go
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 // 年榜
|
|
)
|