init: web_hgdjc_server
This commit is contained in:
@@ -0,0 +1,249 @@
|
||||
package srv_search
|
||||
|
||||
import (
|
||||
"context"
|
||||
"strconv"
|
||||
"videoweb/pub/common/log"
|
||||
"videoweb/pub/common/srvdef"
|
||||
"videoweb/pub/esmanager"
|
||||
"videoweb/pub/models/esmod"
|
||||
"videoweb/pub/models/playletmod"
|
||||
"videoweb/pub/models/playlettagmod"
|
||||
"videoweb/pub/models/playletthememod"
|
||||
|
||||
"go.mongodb.org/mongo-driver/bson"
|
||||
"go.mongodb.org/mongo-driver/mongo/options"
|
||||
)
|
||||
|
||||
var playletESProjection = bson.D{
|
||||
{Key: playletmod.FN.Playlet.Id, Value: 1},
|
||||
{Key: playletmod.FN.Playlet.Status, Value: 1},
|
||||
{Key: playletmod.FN.Playlet.IsFeatured, Value: 1},
|
||||
{Key: playletmod.FN.Playlet.IsRecommend, Value: 1},
|
||||
{Key: playletmod.FN.Playlet.OperateType, Value: 1},
|
||||
{Key: playletmod.FN.Playlet.ShowOnBanner, Value: 1},
|
||||
{Key: playletmod.FN.Playlet.Banner, Value: 1},
|
||||
{Key: playletmod.FN.Playlet.OnlineAt, Value: 1},
|
||||
{Key: playletmod.FN.Playlet.ThemeIds, Value: 1},
|
||||
{Key: playletmod.FN.Playlet.CategoryIds, Value: 1},
|
||||
{Key: playletmod.FN.Playlet.Title, Value: 1},
|
||||
{Key: playletmod.FN.Playlet.PlayName, Value: 1},
|
||||
{Key: playletmod.FN.Playlet.Description, Value: 1},
|
||||
{Key: playletmod.FN.Playlet.Slug, Value: 1},
|
||||
{Key: playletmod.FN.Playlet.Desc, Value: 1},
|
||||
{Key: playletmod.FN.Playlet.Anchor, Value: 1},
|
||||
{Key: playletmod.FN.Playlet.Cover, Value: 1},
|
||||
{Key: playletmod.FN.Playlet.CompressedCover, Value: 1},
|
||||
{Key: playletmod.FN.Playlet.TagIds, Value: 1},
|
||||
{Key: playletmod.FN.Playlet.TotalEpisode, Value: 1},
|
||||
{Key: playletmod.FN.Playlet.UpdateStatus, Value: 1},
|
||||
{Key: playletmod.FN.Playlet.CountBrowse, Value: 1},
|
||||
{Key: playletmod.FN.Playlet.HeatValue, Value: 1},
|
||||
{Key: playletmod.FN.Playlet.CountCollect, Value: 1},
|
||||
{Key: playletmod.FN.Playlet.CountLike, Value: 1},
|
||||
{Key: playletmod.FN.Playlet.VirtualCountLike, Value: 1},
|
||||
{Key: playletmod.FN.Playlet.CreatedAt, Value: 1},
|
||||
{Key: playletmod.FN.Playlet.UpdatedAt, Value: 1},
|
||||
{Key: "seoInfo", Value: 1},
|
||||
}
|
||||
|
||||
// SyncPlayletStatusToES 根据短剧上下架状态同步ES搜索数据
|
||||
func SyncPlayletStatusToES(ctx context.Context, ids []int64, status playletmod.Status) *srvdef.SrvErr {
|
||||
// ES只保留已上架短剧;上架写入/更新索引,下架从索引删除。
|
||||
if len(ids) == 0 {
|
||||
return nil
|
||||
}
|
||||
if esmanager.Instance == nil {
|
||||
log.Error("短剧ES同步失败,ES未初始化", log.Any("短剧ID", ids), log.Any("状态", status))
|
||||
return srvdef.New(srvdef.ErrElsOperError, "", "")
|
||||
}
|
||||
switch status {
|
||||
case playletmod.StatusUp:
|
||||
return upsertPlayletsToES(ctx, ids)
|
||||
case playletmod.StatusDown:
|
||||
return deletePlayletsFromES(ids)
|
||||
default:
|
||||
return nil
|
||||
}
|
||||
}
|
||||
|
||||
// upsertPlayletsToES 批量写入已上架短剧ES文档
|
||||
func upsertPlayletsToES(ctx context.Context, ids []int64) *srvdef.SrvErr {
|
||||
// 只查询已上架数据,避免并发状态变化后把已下架短剧重新写进ES。
|
||||
list, err := playletmod.FindManyPlaylet(ctx, bson.M{
|
||||
playletmod.FN.Playlet.Id: bson.M{"$in": ids},
|
||||
playletmod.FN.Playlet.Status: playletmod.StatusUp,
|
||||
}, options.Find().SetProjection(playletESProjection))
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if len(list) == 0 {
|
||||
return nil
|
||||
}
|
||||
themeNameMap, err := buildPlayletESThemeNameMap(ctx, list)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
tagNameMap, err := buildPlayletESTagNameMap(ctx, list)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
esData := make(esmanager.M, len(list))
|
||||
for _, item := range list {
|
||||
if item == nil {
|
||||
continue
|
||||
}
|
||||
esData[strconv.FormatInt(item.Id, 10)] = playletToESDoc(item, themeNameMap, tagNameMap)
|
||||
}
|
||||
if len(esData) == 0 {
|
||||
return nil
|
||||
}
|
||||
if err = AddMultiDataToES(esmod.GetPlayletIndex(), esData); err != nil {
|
||||
log.Error("批量写入短剧ES失败", log.Any("短剧ID", ids), log.E(err))
|
||||
return err
|
||||
}
|
||||
log.Info("批量写入短剧ES成功", log.Any("数量", len(esData)), log.Any("短剧ID", ids))
|
||||
return nil
|
||||
}
|
||||
|
||||
// deletePlayletsFromES 批量删除短剧ES文档
|
||||
func deletePlayletsFromES(ids []int64) *srvdef.SrvErr {
|
||||
// ES文档ID和Mongo短剧业务ID保持一致,可以直接按ID批量删除。
|
||||
strIds := make([]string, 0, len(ids))
|
||||
for _, id := range ids {
|
||||
if id <= 0 {
|
||||
continue
|
||||
}
|
||||
strIds = append(strIds, strconv.FormatInt(id, 10))
|
||||
}
|
||||
if len(strIds) == 0 {
|
||||
return nil
|
||||
}
|
||||
if err := batchDelFromES(esmod.GetPlayletIndex(), strIds); err != nil {
|
||||
log.Error("批量删除短剧ES失败", log.Any("短剧ID", ids), log.E(err))
|
||||
return err
|
||||
}
|
||||
log.Info("批量删除短剧ES成功", log.Any("数量", len(strIds)), log.Any("短剧ID", ids))
|
||||
return nil
|
||||
}
|
||||
|
||||
// playletToESDoc 转换短剧Mongo数据为ES文档
|
||||
func playletToESDoc(item *playletmod.Playlet, themeNameMap map[int64]string, tagNameMap map[int64]string) *esmod.ESPlaylet {
|
||||
// ES文档保留题材名和标签名,app搜索可直接命中剧名、题材名、简介和标签名。
|
||||
return &esmod.ESPlaylet{
|
||||
Id: item.Id,
|
||||
Status: item.Status,
|
||||
IsFeatured: item.IsFeatured,
|
||||
IsRecommend: item.IsRecommend,
|
||||
OperateType: playletmod.NormalizeOperateType(item.OperateType),
|
||||
ShowOnBanner: item.ShowOnBanner,
|
||||
Banner: item.Banner,
|
||||
OnlineAt: item.OnlineAt,
|
||||
ThemeIds: item.ThemeIds,
|
||||
ThemeNames: playletESNamesByIds(item.ThemeIds, themeNameMap),
|
||||
CategoryIds: item.CategoryIds,
|
||||
Title: item.Title,
|
||||
PlayName: item.PlayName,
|
||||
Description: item.Description,
|
||||
Slug: item.Slug,
|
||||
Desc: item.Desc,
|
||||
Anchor: item.Anchor,
|
||||
Cover: item.DisplayCover(),
|
||||
TagIds: item.TagIds,
|
||||
TagNames: playletESNamesByIds(item.TagIds, tagNameMap),
|
||||
TotalEpisode: item.TotalEpisode,
|
||||
UpdateStatus: item.UpdateStatus,
|
||||
CountBrowse: item.CountBrowse,
|
||||
HeatValue: item.HeatValue,
|
||||
CountCollect: item.CountCollect,
|
||||
CountLike: item.CountLike + item.VirtualCountLike,
|
||||
CreatedAt: item.CreatedAt,
|
||||
UpdatedAt: item.UpdatedAt,
|
||||
SeoInfo: item.SeoInfo,
|
||||
}
|
||||
}
|
||||
|
||||
// buildPlayletESThemeNameMap 批量查询短剧题材名称
|
||||
func buildPlayletESThemeNameMap(ctx context.Context, list playletmod.PlayletList) (map[int64]string, *srvdef.SrvErr) {
|
||||
ids := collectPlayletESIds(list, func(item *playletmod.Playlet) []int64 {
|
||||
return item.ThemeIds
|
||||
})
|
||||
result := make(map[int64]string, len(ids))
|
||||
if len(ids) == 0 {
|
||||
return result, nil
|
||||
}
|
||||
themes, err := playletthememod.FindManyPlayletTheme(ctx, bson.M{
|
||||
playletthememod.FN.PlayletTheme.Id: bson.M{"$in": ids},
|
||||
}, options.Find().SetProjection(bson.D{
|
||||
{Key: playletthememod.FN.PlayletTheme.Id, Value: 1},
|
||||
{Key: playletthememod.FN.PlayletTheme.Name, Value: 1},
|
||||
}))
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
for _, theme := range themes {
|
||||
if theme != nil {
|
||||
result[theme.Id] = theme.Name
|
||||
}
|
||||
}
|
||||
return result, nil
|
||||
}
|
||||
|
||||
// buildPlayletESTagNameMap 批量查询短剧标签名称
|
||||
func buildPlayletESTagNameMap(ctx context.Context, list playletmod.PlayletList) (map[int64]string, *srvdef.SrvErr) {
|
||||
ids := collectPlayletESIds(list, func(item *playletmod.Playlet) []int64 {
|
||||
return item.TagIds
|
||||
})
|
||||
result := make(map[int64]string, len(ids))
|
||||
if len(ids) == 0 {
|
||||
return result, nil
|
||||
}
|
||||
tags, err := playlettagmod.FindManyPlayletTag(ctx, bson.M{
|
||||
playlettagmod.FN.PlayletTag.Id: bson.M{"$in": ids},
|
||||
}, options.Find().SetProjection(bson.D{
|
||||
{Key: playlettagmod.FN.PlayletTag.Id, Value: 1},
|
||||
{Key: playlettagmod.FN.PlayletTag.Name, Value: 1},
|
||||
}))
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
for _, tag := range tags {
|
||||
if tag != nil {
|
||||
result[tag.Id] = tag.Name
|
||||
}
|
||||
}
|
||||
return result, nil
|
||||
}
|
||||
|
||||
// collectPlayletESIds 汇总并去重短剧题材或标签ID
|
||||
func collectPlayletESIds(list playletmod.PlayletList, pick func(item *playletmod.Playlet) []int64) []int64 {
|
||||
result := make([]int64, 0)
|
||||
seen := make(map[int64]struct{})
|
||||
for _, item := range list {
|
||||
if item == nil {
|
||||
continue
|
||||
}
|
||||
for _, id := range pick(item) {
|
||||
if id <= 0 {
|
||||
continue
|
||||
}
|
||||
if _, ok := seen[id]; ok {
|
||||
continue
|
||||
}
|
||||
seen[id] = struct{}{}
|
||||
result = append(result, id)
|
||||
}
|
||||
}
|
||||
return result
|
||||
}
|
||||
|
||||
// playletESNamesByIds 按ID顺序返回ES文档名称集合
|
||||
func playletESNamesByIds(ids []int64, nameMap map[int64]string) []string {
|
||||
result := make([]string, 0, len(ids))
|
||||
for _, id := range ids {
|
||||
if name := nameMap[id]; name != "" {
|
||||
result = append(result, name)
|
||||
}
|
||||
}
|
||||
return result
|
||||
}
|
||||
Reference in New Issue
Block a user