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 // 年榜 )