package service import ( "context" "github.com/prometheus/common/log" "github.com/tidwall/gjson" "gopkg.in/olivere/elastic.v5" "regexp" "search_server/pkg/common" "search_server/pkg/config" "search_server/pkg/es" "search_server/protopb/bom" "strings" ) type BomServiceImpl struct{} func (bs *BomServiceImpl) AutoSpu(ctx context.Context, req *bom.AutoSpuRequest, rsp *bom.AutoSpuResponse) error { goodsNameSlice := AutoSpu(req.GoodsName) if len(goodsNameSlice) == 0 { rsp.ErrorCode = 1 } rsp.Data = goodsNameSlice return nil } func (bs *BomServiceImpl) Recommend(ctx context.Context, req *bom.RecommendRequest, rsp *bom.RecommendResponse) error { if req.Flag == 0 { rsp.ErrorCode = 101 rsp.ErrorMessage = "参数不全" return nil } rsp.Data = Recommend(req) return nil } func NewBomServiceImpl() *BomServiceImpl { return &BomServiceImpl{} } //构建请求参数 func AutoSpu(goodsName string) []string { replace, _ := regexp.Compile("[^A-Za-z0-9]+") goodsName = replace.ReplaceAllString(goodsName, "") goodsName = strings.ToUpper(goodsName) query := getTermQuery(goodsName) source := elastic.NewSearchSource().Query(query) source = source.From(0).Size(10) searchRequestStr, _ := elastic.NewSearchRequest().Source(source).Body() result, err := es.CurlES("lie_spu", searchRequestStr) //只要其中的goods_name if err != nil { log.Error(err) } goodsNameList := make([]string, 0) goodsList := gjson.Get(result, "hits.hits.#._source").Array() for _, goods := range goodsList { goodsName := gjson.Get(goods.String(), "auto_goods_name").String() goodsNameList = append(goodsNameList, goodsName) } return goodsNameList } //构建term条件 func getTermQuery(goodsName string) (query *elastic.BoolQuery) { query = elastic.NewBoolQuery() query.Filter(elastic.NewTermQuery("auto_goods_name", goodsName)) if config.Get("web.mode").String() != "debug" { query.Filter(elastic.NewTermQuery("status", 1)) } query.MustNot(elastic.NewTermQuery("brand_id", 0)) return query } //推荐商品搜索 func Recommend(req *bom.RecommendRequest) (rsp *bom.ResponseData) { var err error //先去请求参数,看是否是参数,如果是参数的话,需要修改请求的商品名称 var goodsName string if req.GoodsName != "" { goodsName, err = SearchAttr(req.GoodsName, req.Encap) } //如果没有型号,但是有参数(参数有可能是型号),那就去匹配参数 if req.GoodsName == "" && req.Attrs != "" { goodsName, err = SearchAttr(req.Attrs, req.Encap) } if goodsName != "" { req.GoodsName = goodsName } //转换请求参数 req = changeRecommendReq(req) //获取需要请求的索引 index := getRecommendSearchIndex(req) //获取es的请求参数 queryJson := getRecommendSearchParams(false, req) result, err := es.CurlES(index, queryJson) if err != nil { log.Error(err) } //获取需要的数据 total := gjson.Get(result, "hits.total").Int() var response bom.ResponseData response.Total = total //获取goods_id列表去商品服务获取商品 list := gjson.Get(result, "hits.hits.#._source").Array() var goodsIdList []string var goodsIdListStr string for _, goods := range list { goodsId := gjson.Get(goods.String(), "goods_id").String() goodsIdList = append(goodsIdList, goodsId) } goodsIdListStr = strings.Join(goodsIdList, ",") goodsList, err := GetGoodsInfo(goodsIdListStr) response.Data = goodsList response.Flag = req.Flag return &response } //处理recommend接口的请求参数 func changeRecommendReq(req *bom.RecommendRequest) (res *bom.RecommendRequest) { //设置默认值 if req.Num == 0 { req.Num = 1 } //转换处理商品名称 replace, _ := regexp.Compile("[^A-Za-z0-9]+") req.GoodsName = replace.ReplaceAllString(req.GoodsName, "") req.GoodsName = strings.ToUpper(req.GoodsName) if req.Flag == 2 { //截取字符后再精确匹配 req.GoodsName = common.SubKeyWordStr(req.GoodsName) } return req } //获取recommend接口需要请求的索引 func getRecommendSearchIndex(req *bom.RecommendRequest) (index string) { index = config.Get("es.hk_delivery_type_supplier").String() //如果是内地收货的情况下 if req.DeliveryType == 1 { index = index + ",liexin_ziying,zhuanmai" } return } //获取请求es的参数 func getRecommendSearchParams(isRawSearch bool, req *bom.RecommendRequest) (result string) { result = getBomTermQuery(req.GoodsName, "", req.Num, isRawSearch) return } //获取bom单的term查询 func getBomTermQuery(goodsName, brandName string, number int32, isRawSearch bool) (result string) { query := elastic.NewBoolQuery() if isRawSearch { field := "auto_goods_name.raw" replace, _ := regexp.Compile("[^A-Za-z0-9]+") goodsName := replace.ReplaceAllString(goodsName, "") goodsName = strings.ToUpper(goodsName) //搜索商品名称 query = query.Filter(elastic.NewTermQuery(field, goodsName)) //判断是否存在brandName,存在就去搜索brandName if brandName != "" { brandName = strings.ToUpper(brandName) query = query.Should(elastic.NewConstantScoreQuery(elastic.NewTermQuery("brand_name", brandName)).Boost(2)) } //搜索库存 query = query.Should(elastic.NewConstantScoreQuery(elastic.NewRangeQuery("stock").Gte(number))) } else { field := "auto_goods_name" query = query.Must(elastic.NewTermQuery(field, goodsName)) } if config.Get("web.mode").String() != "debug" { query.Filter(elastic.NewTermQuery("status", 1)) } source := elastic.NewSearchSource().Query(query) source.From(0) if isRawSearch { source.Size(100) } else { source.Size(1) } source.Sort("_score", false).Sort("sort", false).Sort("single_price", true) queryRequest := elastic.NewSearchRequest().Source(source) result, _ = queryRequest.Body() return result }