Initial commit: web_hghl_server
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
This commit is contained in:
@@ -0,0 +1,153 @@
|
||||
package esmod
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"videoweb/app/api/proto"
|
||||
"videoweb/pub/common/log"
|
||||
"videoweb/pub/common/srvdef"
|
||||
"videoweb/pub/esmanager"
|
||||
"videoweb/pub/models/videoinformationmod"
|
||||
"videoweb/pub/pubdef"
|
||||
)
|
||||
|
||||
// SearchVideo 根据关键字搜索媒体
|
||||
func SearchVideo(content string, from int64, size int64, sort string, isAv bool) (int64, []*videoinformationmod.VideoInformation, *srvdef.SrvErr) {
|
||||
fields := []string{FN.ESVideo.Title, FN.ESVideo.Bango, FN.ESVideo.IssuedBrand, FN.ESVideo.Keyworlds, FN.ESVideo.Desc}
|
||||
mediaType := videoinformationmod.MediaType_Video
|
||||
if isAv {
|
||||
mediaType = videoinformationmod.MediaType_AV
|
||||
}
|
||||
must := esmanager.M{
|
||||
"bool": esmanager.M{
|
||||
"must": esmanager.A{
|
||||
{"multi_match": esmanager.M{
|
||||
"query": content,
|
||||
"type": "best_fields",
|
||||
"fields": fields},
|
||||
},
|
||||
{"term": esmanager.M{FN.ESVideo.Status: pubdef.InformationStatusVerifyOK}},
|
||||
{"term": esmanager.M{FN.ESVideo.MediaType: mediaType}},
|
||||
},
|
||||
},
|
||||
}
|
||||
switch sort {
|
||||
case string(proto.SearchSortTypeHot):
|
||||
must = esmanager.M{
|
||||
"function_score": esmanager.M{
|
||||
"query": esmanager.M{
|
||||
"bool": esmanager.M{
|
||||
"must": esmanager.A{
|
||||
{"multi_match": esmanager.M{
|
||||
"query": content,
|
||||
"type": "best_fields",
|
||||
"fields": fields,
|
||||
}},
|
||||
{"term": esmanager.M{FN.ESVideo.Status: pubdef.InformationStatusVerifyOK}},
|
||||
{"term": esmanager.M{FN.ESVideo.MediaType: mediaType}},
|
||||
},
|
||||
},
|
||||
},
|
||||
"functions": esmanager.A{
|
||||
esmanager.M{
|
||||
"field_value_factor": esmanager.M{
|
||||
"field": FN.ESVideo.WatchTimes,
|
||||
"factor": 1.0,
|
||||
"modifier": "none",
|
||||
},
|
||||
},
|
||||
},
|
||||
"score_mode": "sum",
|
||||
"boost_mode": "multiply",
|
||||
},
|
||||
}
|
||||
case string(proto.SearchSortTypeNew):
|
||||
must = esmanager.M{
|
||||
"bool": esmanager.M{
|
||||
"must": esmanager.A{
|
||||
{"multi_match": esmanager.M{
|
||||
"query": content,
|
||||
"type": "best_fields",
|
||||
"fields": fields},
|
||||
},
|
||||
{"term": esmanager.M{FN.ESVideo.Status: pubdef.InformationStatusVerifyOK}},
|
||||
{"term": esmanager.M{FN.ESVideo.MediaType: mediaType}},
|
||||
},
|
||||
"should": esmanager.A{
|
||||
{"range": esmanager.M{FN.ESVideo.AddedTime: esmanager.M{"gte": "now-30d/d", "boost": 2.0}}}, //7天内提升4倍权重
|
||||
{"range": esmanager.M{FN.ESVideo.AddedTime: esmanager.M{"gte": "now-180d/d", "boost": 1.5}}}, // 30天内提升3倍权重
|
||||
{"range": esmanager.M{FN.ESVideo.AddedTime: esmanager.M{"gte": "now-365d/d", "boost": 1.1}}}, // 90天内提升1.5倍权重
|
||||
},
|
||||
"minimum_should_match": 0, // 允许不匹配任何should条件
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
query := esmanager.M{
|
||||
"query": must,
|
||||
"sort": esmanager.A{
|
||||
esmanager.M{"_score": esmanager.M{"order": "desc"}},
|
||||
},
|
||||
"from": from,
|
||||
"size": size,
|
||||
}
|
||||
|
||||
log.Info("(esmod:SearchVideo) 执行搜索",
|
||||
log.Any("index", videoIndex),
|
||||
log.Any("keywords", content),
|
||||
log.Any("sort", sort),
|
||||
log.Any("from", from),
|
||||
log.Any("size", size))
|
||||
videos := &ESVideoHits{}
|
||||
err := esmanager.Instance.Search(videoIndex, videos, query)
|
||||
if err != nil {
|
||||
info := fmt.Sprintf(
|
||||
"(esmod:SearchVideo) Search failed! err:%+v:", err)
|
||||
log.Warn(info,
|
||||
log.Any("keywords", content),
|
||||
log.Any("from", from),
|
||||
log.Any("size", size))
|
||||
return 0, nil, srvdef.New(srvdef.ErrElsOperError, "", "")
|
||||
}
|
||||
total := int64(0)
|
||||
rslData := make([]*videoinformationmod.VideoInformation, 0)
|
||||
if videos != nil && videos.Hits != nil && len(videos.Hits) > 0 {
|
||||
total = videos.Total.Value
|
||||
for _, video := range videos.Hits {
|
||||
rslData = append(rslData, EsVideoInfoToData(video.Source))
|
||||
}
|
||||
}
|
||||
log.Info("(esmod:SearchVideo) 搜索完成",
|
||||
log.Any("index", videoIndex),
|
||||
log.Any("keywords", content),
|
||||
log.Any("total", total),
|
||||
log.Any("hits", len(rslData)))
|
||||
return total, rslData, nil
|
||||
}
|
||||
|
||||
func EsVideoInfoToData(esInfo *ESVideo) *videoinformationmod.VideoInformation {
|
||||
info := &videoinformationmod.VideoInformation{
|
||||
Id: esInfo.Id,
|
||||
Title: esInfo.Title,
|
||||
MediaType: esInfo.MediaType,
|
||||
AddedTime: esInfo.AddedTime,
|
||||
CreatorId: esInfo.CreatorId,
|
||||
CreatorName: esInfo.CreatorName,
|
||||
Keyworld: esInfo.Keyworld,
|
||||
FirstTag: esInfo.FirstTag,
|
||||
SecondTags: esInfo.SecondTags,
|
||||
CoverImg: esInfo.CoverImg,
|
||||
Desc: esInfo.Desc,
|
||||
Remark: esInfo.Remark,
|
||||
Nodes: esInfo.Nodes,
|
||||
Status: esInfo.Status,
|
||||
Video: esInfo.Video,
|
||||
Tags: esInfo.Tags,
|
||||
IsHot: esInfo.IsHot,
|
||||
Sort: esInfo.Sort,
|
||||
Real: esInfo.Real,
|
||||
VideoCount: esInfo.VideoCount,
|
||||
UpdatedAt: esInfo.UpdatedAt,
|
||||
CreatedAt: esInfo.CreatedAt,
|
||||
}
|
||||
return info
|
||||
}
|
||||
Reference in New Issue
Block a user