126 lines
3.2 KiB
Go
126 lines
3.2 KiB
Go
package hotvalue
|
||
|
||
import (
|
||
"91porn-server/common/log"
|
||
"91porn-server/models/v/cmtmod"
|
||
"91porn-server/models/v/mediamod"
|
||
"91porn-server/models/v/vidmod"
|
||
"github.com/golang-module/carbon/v2"
|
||
"go.mongodb.org/mongo-driver/bson"
|
||
"go.mongodb.org/mongo-driver/bson/primitive"
|
||
"go.mongodb.org/mongo-driver/mongo"
|
||
"math"
|
||
"time"
|
||
)
|
||
|
||
type updateFn func(models []mongo.WriteModel) error
|
||
|
||
var (
|
||
actions = map[string]updateFn{
|
||
cmtmod.OTypeVideo: vidmod.Bulk,
|
||
cmtmod.OTypeCartoon: mediamod.Bulk,
|
||
}
|
||
)
|
||
|
||
// ResetHot 重置热度值
|
||
func ResetHot() {
|
||
start := carbon.NewCarbon().SubDays(30).StdTime()
|
||
end := time.Now()
|
||
writes := make([]mongo.WriteModel, 0)
|
||
|
||
for objType, fn := range actions {
|
||
skip := 0
|
||
limit := 100
|
||
|
||
for {
|
||
// 获取30天内有评论的objID
|
||
objIds, hasNext, err := cmtmod.GetObjIdsBetweenTime(objType, start, end, skip, limit)
|
||
if err != nil {
|
||
log.Error("Job ResetHot cmtmod.GetObjIdsBetweenTime fail", log.E(err))
|
||
return
|
||
}
|
||
|
||
for _, objId := range objIds {
|
||
hotData := resetObjectHot(objId, objType, start, end)
|
||
if len(hotData) == 0 {
|
||
continue
|
||
}
|
||
update := mongo.NewUpdateOneModel().SetFilter(bson.M{"_id": objId}).SetUpdate(hotData).SetUpsert(true)
|
||
writes = append(writes, update)
|
||
}
|
||
|
||
if len(writes) > 0 {
|
||
err = fn(writes)
|
||
if err != nil {
|
||
log.Error("Job ResetHot fail", log.E(err),
|
||
log.Any("objType", objType),
|
||
log.Any("skip", skip))
|
||
}
|
||
}
|
||
writes = writes[0:0]
|
||
skip = skip + limit
|
||
|
||
if !hasNext {
|
||
break
|
||
}
|
||
}
|
||
}
|
||
}
|
||
|
||
// 热度=Z历史所有评论数 × 30% × e^(−{评论天数}×0.1)
|
||
//+Z近7天评论数 × 70%
|
||
|
||
func resetObjectHot(objId primitive.ObjectID, objType string, start, end time.Time) bson.M {
|
||
// 暂时只支持视频和ACG的评论
|
||
if objType != cmtmod.OTypeVideo && objType != cmtmod.OTypeCartoon {
|
||
return nil
|
||
}
|
||
// 获取该对性一段时间内,按天分组,每天的评论总数
|
||
list, err := cmtmod.GetCountGroupByDay(objId, start, end)
|
||
if err != nil {
|
||
log.Error("Job ResetHot resetObjectHot cmtmod.GetCountGroupByDay fail", log.E(err))
|
||
return nil
|
||
}
|
||
var historyHot float64
|
||
var sevenDayCount float64
|
||
// 计算出该对象的热度值
|
||
for _, v := range list {
|
||
// 获取跟今天相差的天数
|
||
day := float64(carbon.Now().DiffAbsInDays(carbon.ParseByFormat(v.Time, "Y-m-d")))
|
||
// 计算历史评论热度
|
||
hot := calculateCommentScore(v.Count, day)
|
||
historyHot = historyHot + hot
|
||
// 累加近七天的总数
|
||
if day <= 7 {
|
||
sevenDayCount = sevenDayCount + float64(v.Count)
|
||
}
|
||
}
|
||
currentHot := historyHot + sevenDayCount*0.7
|
||
log.Info("Job ResetHot resetObjectHot result", log.Any("hot", currentHot))
|
||
|
||
data := bson.M{"hot": currentHot}
|
||
|
||
if objType == cmtmod.OTypeVideo {
|
||
data["updatedAt"] = time.Now()
|
||
} else {
|
||
data["updateTime"] = time.Now()
|
||
}
|
||
|
||
return bson.M{"$set": data}
|
||
}
|
||
|
||
func calculateCommentScore(totalComments int64, daysSinceComment float64) float64 {
|
||
// Ensure we don't have negative days
|
||
if daysSinceComment < 0 {
|
||
daysSinceComment = 0
|
||
}
|
||
|
||
// Calculate the decay factor: e^(-days * 0.1)
|
||
decayFactor := math.Exp(-daysSinceComment * 0.1)
|
||
|
||
// Calculate the final score: totalComments * 0.3 * decayFactor
|
||
score := float64(totalComments) * 0.3 * decayFactor
|
||
|
||
return score
|
||
}
|