@@ -0,0 +1,125 @@
|
||||
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
|
||||
}
|
||||
Reference in New Issue
Block a user