Files
go_process_manager/internal/app/logic/bleve.go
2025-07-09 10:49:27 +08:00

136 lines
3.5 KiB
Go

package logic
import (
"time"
"github.com/blevesearch/bleve/v2"
"github.com/blevesearch/bleve/v2/search"
"github.com/google/uuid"
"github.com/lzh-1625/go_process_manager/internal/app/model"
logger "github.com/lzh-1625/go_process_manager/log"
gse "github.com/vcaesar/gse-bleve"
)
type bleveLogic struct {
index bleve.Index
}
var BleveLogic = new(bleveLogic)
func (b *bleveLogic) InitBleve() {
opt := gse.Option{
Dicts: "embed, zh",
Stop: "",
Opt: "search-hmm",
Trim: "trim",
}
indexMapping, err := gse.NewMapping(opt)
if err != nil {
logger.Logger.Errorw("bleve init fail", "err", err)
return
}
mapping := bleve.NewDocumentMapping()
log := bleve.NewTextFieldMapping()
log.Index = true
time := bleve.NewNumericFieldMapping()
time.Index = true
name := bleve.NewKeywordFieldMapping()
name.Index = true
using := bleve.NewKeywordFieldMapping()
using.Index = true
mapping.AddFieldMappingsAt("log", log)
mapping.AddFieldMappingsAt("time", time)
mapping.AddFieldMappingsAt("name", name)
mapping.AddFieldMappingsAt("using", using)
indexMapping.AddDocumentMapping("server_log_v1", mapping)
index, err := bleve.Open("log.bleve")
if err != nil {
index, err = bleve.New("log.bleve", indexMapping)
if err != nil {
logger.Logger.Errorw("bleve init error", "err", err)
return
}
}
b.index = index
}
func (b *bleveLogic) Insert(logContent string, processName string, using string, ts int64) {
if err := b.index.Index(uuid.NewString(), model.ProcessLog{
Log: logContent,
Name: processName,
Using: using,
Time: ts,
}); err != nil {
logger.Logger.Warnw("bleve log insert failed", "err", err)
}
}
func (b *bleveLogic) Search(req model.GetLogReq, filterProcessName ...string) (result model.LogResp) {
buildQuery := bleve.NewBooleanQuery()
if req.Match.Log != "" {
logQuery := bleve.NewMatchQuery(req.Match.Log)
logQuery.SetField("log")
buildQuery.AddMust(logQuery)
}
if req.Match.Name != "" {
nameQuery := bleve.NewTermQuery(req.Match.Name)
nameQuery.SetField("name")
buildQuery.AddMust(nameQuery)
}
if req.Match.Using != "" {
usingQuery := bleve.NewWildcardQuery("*" + req.Match.Using + "*")
usingQuery.SetField("using")
buildQuery.AddMust(usingQuery)
}
if req.TimeRange.EndTime != 0 || req.TimeRange.StartTime != 0 {
st := float64(req.TimeRange.StartTime)
et := float64(req.TimeRange.EndTime)
timeQuery := bleve.NewNumericRangeQuery(&st, &et)
buildQuery.AddMust(timeQuery)
} else {
st := float64(0)
et := float64(time.Now().UnixMilli())
timeQuery := bleve.NewNumericRangeQuery(&st, &et)
buildQuery.AddMust(timeQuery)
}
if len(filterProcessName) != 0 {
for _, v := range filterProcessName {
filterQuery := bleve.NewTermQuery(v)
filterQuery.SetField("name")
buildQuery.AddShould(filterQuery)
}
}
sortArgs := ([]string{"-_score"})
if req.Sort == "desc" {
sortArgs = append(sortArgs, "-time")
}
if req.Sort == "asc" {
sortArgs = append(sortArgs, "time")
}
res, err := b.index.Search(&bleve.SearchRequest{
Query: buildQuery,
Fields: []string{"log", "name", "using", "time"},
From: req.Page.From,
Size: req.Page.Size,
Sort: search.ParseSortOrderStrings(sortArgs),
})
if err != nil {
logger.Logger.Warnw("bleve search failed", "err", err)
return
}
data := []*model.ProcessLog{}
for _, v := range res.Hits {
data = append(data, &model.ProcessLog{
Log: v.Fields["log"].(string),
Time: int64(v.Fields["time"].(float64)),
Using: v.Fields["using"].(string),
Name: v.Fields["name"].(string),
})
}
result.Data = data
result.Total = int64(res.Total)
return
}