82 lines
2.3 KiB
Go
82 lines
2.3 KiB
Go
package playletser
|
|
|
|
import (
|
|
"context"
|
|
"time"
|
|
"videoweb/pub/common/srvdef"
|
|
"videoweb/pub/models/playletmod"
|
|
|
|
"go.mongodb.org/mongo-driver/bson"
|
|
"go.mongodb.org/mongo-driver/mongo/options"
|
|
)
|
|
|
|
const operateRandomModulus int64 = 2147483647
|
|
|
|
func operateListFilter(typ int64) bson.M {
|
|
filter := homeUpPlayletFilter(nil)
|
|
if typ == operateListOriginal {
|
|
filter[playletmod.FN.Playlet.IsRecommend] = true
|
|
}
|
|
return filter
|
|
}
|
|
|
|
func operateListSort(typ int64) bson.D {
|
|
if typ == operateListHot {
|
|
return bson.D{{Key: playletmod.FN.Playlet.HeatValue, Value: -1}, {Key: playletmod.FN.Playlet.Id, Value: -1}}
|
|
}
|
|
return playletRecentlyUpdatedSort()
|
|
}
|
|
|
|
// findRandomOperatePlaylets 按每日固定的伪随机顺序分页查询短剧
|
|
func findRandomOperatePlaylets(ctx context.Context, filter bson.M, skip, limit int64, now time.Time) (playletmod.PlayletList, *srvdef.SrvErr) {
|
|
var rows []struct {
|
|
Id int64 `bson:"_id"`
|
|
}
|
|
if err := playletmod.AggregatePlaylet(ctx, &rows, operateRandomPipeline(filter, skip, limit, now)); err != nil {
|
|
return nil, err
|
|
}
|
|
ids := make([]int64, 0, len(rows))
|
|
for _, row := range rows {
|
|
ids = append(ids, row.Id)
|
|
}
|
|
if len(ids) == 0 {
|
|
return make(playletmod.PlayletList, 0), nil
|
|
}
|
|
queryFilter := bson.M{playletmod.FN.Playlet.Id: bson.M{"$in": ids}}
|
|
for key, value := range filter {
|
|
queryFilter[key] = value
|
|
}
|
|
list, err := playletmod.FindManyPlaylet(ctx, queryFilter, options.Find().SetProjection(playletHomeProjection))
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
byID := make(map[int64]*playletmod.Playlet, len(list))
|
|
for _, item := range list {
|
|
if item != nil {
|
|
byID[item.Id] = item
|
|
}
|
|
}
|
|
ordered := make(playletmod.PlayletList, 0, len(ids))
|
|
for _, id := range ids {
|
|
if item := byID[id]; item != nil {
|
|
ordered = append(ordered, item)
|
|
}
|
|
}
|
|
return ordered, nil
|
|
}
|
|
|
|
func operateRandomPipeline(filter bson.M, skip, limit int64, now time.Time) []bson.M {
|
|
day := (now.Unix() + 8*60*60) / (24 * 60 * 60)
|
|
factor := int64(48271) + day%997*2767
|
|
idMod := bson.M{"$mod": bson.A{"$_id", operateRandomModulus}}
|
|
score := bson.M{"$mod": bson.A{bson.M{"$multiply": bson.A{idMod, factor}}, operateRandomModulus}}
|
|
return []bson.M{
|
|
{"$match": filter},
|
|
{"$project": bson.M{"_id": 1}},
|
|
{"$addFields": bson.M{"randomScore": score}},
|
|
{"$sort": bson.D{{Key: "randomScore", Value: 1}, {Key: "_id", Value: 1}}},
|
|
{"$skip": skip},
|
|
{"$limit": limit},
|
|
}
|
|
}
|