Commit 2b9184b3 by mushishixian

品牌映射

parent 5a658fa0
package common
import (
"bom_server/internal/model"
"strings"
)
//去除两端空格
func TrimBomItemSpace(bomItems []model.BomItem) (result []model.BomItem) {
for key, item := range bomItems {
bomItems[key].BrandName = strings.TrimSpace(item.BrandName)
bomItems[key].GoodsName = strings.TrimSpace(item.GoodsName)
bomItems[key].Attrs = strings.TrimSpace(item.Attrs)
bomItems[key].Encap = strings.TrimSpace(item.Encap)
}
return bomItems
}
......@@ -9,6 +9,7 @@ import (
"context"
"fmt"
"github.com/gomodule/redigo/redis"
"github.com/syyongx/php2go"
"github.com/tidwall/gjson"
es "gopkg.in/olivere/elastic.v5"
"regexp"
......@@ -17,7 +18,6 @@ import (
)
//根据参数去匹配商品
func MatchGoodsNameByAttrs(bomItems []model.BomItem) (result []model.BomItem, err error) {
client, err := es.NewClient(es.SetURL(configs.ESSetting.Url))
if err != nil {
......@@ -31,12 +31,12 @@ func MatchGoodsNameByAttrs(bomItems []model.BomItem) (result []model.BomItem, er
for _, item := range bomItems {
//如果有型号,但是型号有可能是参数,所以先去匹配下参数,有的话转成对应的型号
if item.GoodsName != "" && item.Attrs == "" {
search = searchAttr(item.GoodsName, item.BrandName, item.Encap, search)
search = searchAttr(item, search)
searchFlag = true
}
//如果没有型号,但是有参数(参数有可能是型号),那就去匹配参数
if item.GoodsName == "" && item.Attrs != "" {
search = searchAttr(item.Attrs, item.BrandName, item.Encap, search)
search = searchAttr(item, search)
searchFlag = true
}
}
......@@ -56,7 +56,6 @@ func MatchGoodsNameByAttrs(bomItems []model.BomItem) (result []model.BomItem, er
if responses.Hits != nil {
for _, hit := range responses.Hits.Hits {
res, _ := hit.Source.MarshalJSON()
//CS0805KKX7R9BB105
if bomItems[key].GoodsName == "" {
bomItems[key].GoodsName = gjson.Get(string(res), "goods_name").String()
}
......@@ -67,9 +66,9 @@ func MatchGoodsNameByAttrs(bomItems []model.BomItem) (result []model.BomItem, er
return
}
func searchAttr(attrOrigin, brandName, encap string, search *es.MultiSearchService) (result *es.MultiSearchService) {
func searchAttr(bomItem model.BomItem, search *es.MultiSearchService) (result *es.MultiSearchService) {
//先去切割参数得到参数列表
attrs := splitAttrs(attrOrigin)
attrs := splitAttrs(bomItem.Attrs)
//当切割出来的参数大于1个的时候,就要去针对每个参数进行里面再一次提纯
if len(attrs) > 1 {
for key, attr := range attrs {
......@@ -96,37 +95,45 @@ func searchAttr(attrOrigin, brandName, encap string, search *es.MultiSearchServi
}
}
//单独针对封装进行转换
if encap != "" {
if bomItem.Encap != "" {
//先提取出纯数字
numberR, _ := regexp.Compile(mapping.PureNumberRegular)
pureNumber := numberR.FindString(encap)
pureNumber := numberR.FindString(bomItem.Encap)
//再去找对应属性
attrName, _ := redis.String(gredis.HGet("sku_map2", pureNumber))
if attrName != "" {
attrValue := attrName + "€" + pureNumber
attrsSlice = append(attrsSlice, attrValue)
if !php2go.InArray(attrValue, attrsSlice) {
attrsSlice = append(attrsSlice, attrValue)
}
}
}
query := getQuery(attrsSlice)
if brandName != "" && len(attrsSlice) > 0 {
//提取全英文,转成大写
if strings.Contains(brandName, " ") {
//有空格隔开只取第一个
brandName = strings.Split(brandName, " ")[0]
//如果ZyBrandId不为空,则代表匹配到了映射id,可以直接用must去查询
if bomItem.ZyBrandId != "" && len(attrsSlice) > 0 {
query.Should(es.NewTermQuery("brand_name", bomItem.ZyBrandName))
} else {
if bomItem.BrandName != "" && len(attrsSlice) > 0 {
brandName := bomItem.BrandName
//提取全英文,转成大写
if strings.Contains(brandName, " ") {
//有空格隔开只取第一个
brandName = strings.Split(brandName, " ")[0]
}
//转成全大写,因为ES存的是大写
brandName = strings.ToUpper(brandName)
//去除特殊符号和中文等等
r1, _ := regexp.Compile(`/[^A-Za-z0-9]+/`)
brandName = r1.ReplaceAllString(brandName, "")
query.Should(es.NewTermQuery("brand_name", brandName))
}
//转成全大写,因为ES存的是大写
brandName = strings.ToUpper(brandName)
//去除特殊符号和中文等等
r1, _ := regexp.Compile(`/[^A-Za-z0-9]+/`)
brandName = r1.ReplaceAllString(brandName, "")
query.Should(es.NewTermQuery("brand_name", brandName))
}
source := es.NewSearchSource().Query(query)
source.Sort("_score", false)
source.Sort("brand_sort", true)
source = source.From(0).Size(1)
searchRequest := es.NewSearchRequest().Source(source)
//fmt.Println(searchRequest.Body())
return search.Add(searchRequest)
}
......@@ -152,7 +159,6 @@ func splitAttrs(attrs string) (result []string) {
if len(result) > 1 {
return
}
//按照分隔符切完了,再去每个去正则提取
return
}
......
......@@ -50,17 +50,10 @@ func BatchSaveMatchings(bomId int, matchingList []model.BomItemMatching) (err er
}
now := time.Now().Unix()
var itemStatus int
//if matching.IsBuy == 1 && matching.Price != 0 && matching.Stock != 0 {
// itemStatus = 2
// //库存为0或者价格为0,要放到待确认
//
//} else if matching.Price == 0 || matching.Stock == 0 {
// itemStatus = 4
//}
if matching.IsBuy == 1 {
itemStatus = 2
}else{
itemStatus =3
} else {
itemStatus = 3
}
err = model.Db.Table("lie_bom_item_"+tableEnd).Where("bom_item_id = ?", matching.BomItemID).
Updates(map[string]interface{}{"item_status": itemStatus, "update_time": now}).Error
......
package logic
import "bom_server/internal/model"
import (
"bom_server/configs"
"bom_server/internal/model"
"context"
"github.com/tidwall/gjson"
es "gopkg.in/olivere/elastic.v5"
"regexp"
"strings"
)
//和品牌映射有关的逻辑
func GetBrandMap(bomItems []model.BomItem) (result []model.BomItem, err error) {
client, err := es.NewClient(es.SetURL(configs.ESSetting.Url))
if err != nil {
return
}
index := "stand_brand"
search := client.MultiSearch().Index(index)
for _, bomItem := range bomItems {
search = searchBrandMap(bomItem, search)
}
res, err := search.Do(context.Background())
if err != nil {
return
}
if len(res.Responses) == 0 {
return
}
//因为是多重查询,所以会有多套结果
for key, responses := range res.Responses {
//有数据进行转换
if responses.Hits != nil {
var lyBrandIds []string
for _, hit := range responses.Hits.Hits {
res, _ := hit.Source.MarshalJSON()
lyIdArray := gjson.Get(string(res), "attrs.#.attr_brand_id").Array()
for _, id := range lyIdArray {
idSlice := strings.Split(id.String(), ",")
lyBrandIds = append(lyBrandIds, idSlice...)
}
bomItems[key].ZyBrandId = hit.Id
bomItems[key].ZyBrandName = gjson.Get(string(res), "stand_zy_brand_name").String()
}
bomItems[key].LyBrandIds = lyBrandIds
}
}
result = bomItems
return
}
//根据用户输入的品牌获取映射后的品牌,没有映射的话不变,有的话变
func getBrandMap(bomItems []model.BomItem) {
func searchBrandMap(bomItem model.BomItem, search *es.MultiSearchService) (result *es.MultiSearchService) {
query := getBrandMapQuery(bomItem)
source := es.NewSearchSource().Query(query)
source = source.From(0).Size(1)
searchRequest := es.NewSearchRequest().Source(source)
search.Add(searchRequest)
return search
}
//获取品牌映射搜索的查询条件
func getBrandMapQuery(bomItem model.BomItem) (query *es.BoolQuery) {
var subQuery *es.TermQuery
var nestedQuery *es.NestedQuery
query = es.NewBoolQuery()
brandName := bomItem.BrandName
brandName = strings.ToUpper(brandName)
//提取出纯中文
r, _ := regexp.Compile("[\u4e00-\u9fa5]+")
chineseBrandName := r.FindString(brandName)
if chineseBrandName != "" {
query.Should(es.NewMatchQuery("brand_name_cn", chineseBrandName))
}
//提取出纯英文
re, _ := regexp.Compile("[A-Za-z0-9]+")
englishBrandName := re.FindString(brandName)
subQuery = es.NewTermQuery("attrs.attr_brand_name", englishBrandName)
nestedQuery = es.NewNestedQuery("attrs", subQuery)
query.Should(nestedQuery)
query.MinimumNumberShouldMatch(1)
return query
}
//
......@@ -4,6 +4,7 @@ import (
"bom_server/configs"
"bom_server/internal/model"
"encoding/json"
"fmt"
"github.com/imroc/req"
"github.com/tidwall/gjson"
"strings"
......@@ -29,7 +30,7 @@ func UpdateGoodsData(goodsMapList []GoodsMap) (err error) {
goodsIds = append(goodsIds, goodsMap.GoodsId)
}
goodsIdsStr := strings.Join(goodsIds, ",")
//fmt.Println(goodsIdsStr)
fmt.Println(goodsIdsStr)
goodsList, err := GetGoodsInfo(goodsIdsStr)
if len(goodsMapList) != 0 {
bomId = goodsMapList[0].BomId
......@@ -59,6 +60,7 @@ func UpdateGoodsData(goodsMapList []GoodsMap) (err error) {
}
}
}
err = BatchSaveMatchings(bomId, bomMatchingList)
if err != nil {
return
......@@ -167,7 +169,7 @@ func MatchGoodsInfo(goods model.ApiGoods, goodsMap GoodsMap) (bomMatching model.
Mpl: goods.Mpl,
Mpq: goods.Mpq,
Encap: goods.Encap,
Status: goods.Status,
Status: 1,
AddTime: int(time.Now().Unix()),
}
/**
......
......@@ -7,6 +7,7 @@ import (
"context"
"encoding/json"
"errors"
"fmt"
"math"
"regexp"
"strings"
......@@ -76,11 +77,15 @@ func SearchGoods(bomId int, bomItems []model.BomItem, deliveryType, sort int, wg
if len(bomItems) == 0 {
return
}
//去除首尾空格
bomItems = common.TrimBomItemSpace(bomItems)
client, err := es.NewClient(es.SetURL(configs.ESSetting.Url))
if err != nil {
panic(err)
}
defer client.Stop()
//先去查询品牌映射,有映射关系的,就用映射关系得到的brand_id进行查询
bomItems, err = GetBrandMap(bomItems)
//匹配之前,去遍历bom_item,把没有型号名称但是有参数的bom_item进行型号补充
bomItems, err = MatchGoodsNameByAttrs(bomItems)
//第一次先去精确匹配
......@@ -236,7 +241,7 @@ func search(index string, bomId int, bomItems []model.BomItem, deliveryType, sor
bom.GoodsName = bom.Attrs
}
//构建一个goods_name对应的bomItems列表
searchRequest := getSearchParams(index, bom.GoodsName, bom.BrandName, sort, bom.Number, rawSearch)
searchRequest := getSearchParams(bom, sort, rawSearch)
searchFlag = true
search.Add(searchRequest)
}
......@@ -281,48 +286,57 @@ func search(index string, bomId int, bomItems []model.BomItem, deliveryType, sor
}
//构建请求参数
func getSearchParams(index, goodsName, brandName string, sort, number int, flag bool) (searchRequest *es.SearchRequest) {
query := getTermQuery(goodsName, brandName, sort, number, flag)
func getSearchParams(bomItem model.BomItem, sort int, flag bool) (searchRequest *es.SearchRequest) {
query := getTermQuery(bomItem, sort, flag)
source := es.NewSearchSource().Query(query)
if sort == 1 {
source.Sort("_score", false)
source.Sort("sort", false)
source.Sort("stock", false)
source.Sort("single_price", true)
}
//要去判断sort,sort=2是按照价格排序
if sort == 2 {
source.Sort("_score", false)
source.Sort("single_price", true)
//sort=3是按照库存排序
} else if sort == 3 {
source.Sort("stock_sort", false)
source.Sort("_score", false)
source.Sort("stock", false)
}
source.Sort("_score", false)
source = source.From(0).Size(1)
searchRequest = es.NewSearchRequest().Source(source)
fmt.Println(searchRequest.Body())
return searchRequest
}
//构建term条件
func getTermQuery(goodsName, brandName string, sort, number int, flag bool) (query *es.BoolQuery) {
func getTermQuery(bomItem model.BomItem, sort int, flag bool) (query *es.BoolQuery) {
query = es.NewBoolQuery()
if flag {
field := "auto_goods_name.raw"
replace, _ := regexp.Compile("[^A-Za-z0-9]+")
goodsName := replace.ReplaceAllString(goodsName, "")
goodsName := replace.ReplaceAllString(bomItem.GoodsName, "")
goodsName = strings.ToUpper(goodsName)
//搜索商品名称
query = query.Filter(es.NewTermQuery(field, goodsName))
//判断是否存在brandName,存在就去搜索brandName
if brandName != "" {
brandName = strings.ToUpper(brandName)
query = query.Should(es.NewConstantScoreQuery(es.NewTermQuery("brand_name", brandName)).Boost(2))
//判断是否存在brandName并且匹配不到对应的标准品牌
if bomItem.BrandName != "" {
bomItem.BrandName = strings.ToUpper(bomItem.BrandName)
query = query.Should(es.NewConstantScoreQuery(es.NewTermQuery("brand_name", bomItem.BrandName)).Boost(2))
}
//搜索库存
query = query.Should(es.NewConstantScoreQuery(es.NewRangeQuery("stock").Gte(number)))
query = query.Should(es.NewConstantScoreQuery(es.NewRangeQuery("stock").Gte(bomItem.Number)))
} else {
field := "auto_goods_name"
query = query.Must(es.NewTermQuery(field, goodsName))
query = query.Must(es.NewTermQuery(field, bomItem.GoodsName))
}
//对品牌进行判断搜索,如果能匹配到对应的自营标准品牌(那么同时也有对应的联营品牌)
if bomItem.ZyBrandId != "" {
query.Should(es.NewTermQuery("brand_id", bomItem.ZyBrandId))
for _, id := range bomItem.LyBrandIds {
query.Should(es.NewTermQuery("brand_id", id))
}
}
//按价格排序
if sort == 2 {
......@@ -332,20 +346,8 @@ func getTermQuery(goodsName, brandName string, sort, number int, flag bool) (que
if sort == 3 {
query = query.Filter(es.NewRangeQuery("stock").Gt(0))
}
//query = query.Filter(es.NewRangeQuery("single_price").Gt(0))
//query = query.Filter(es.NewRangeQuery("stock").Gt(0))
if configs.ApiSetting.Mode != "debug" {
query = query.Filter(es.NewTermQuery("status", 1))
}
//query = query.Filter(es.NewRangeQuery("single_price").Gt(0))
//src, err := query.Source()
//if err != nil {
// panic(err)
//}
//data, err := json.MarshalIndent(src, "", " ")
//if err != nil {
// panic(err)
//}
//fmt.Println(string(data))
return query
}
......@@ -23,9 +23,11 @@ type BomItem struct {
UpdateTime int `json:"update_time"`
//映射后的自营品牌id
ZyBrandId int `json:"-"`
ZyBrandId string `json:"-"`
//映射后的联营品牌id
LyBrandId int `json:"-"`
LyBrandIds []string `json:"-"`
//映射后的品牌名称(自营品牌名称)
ZyBrandName string `json:"-"`
Matching BomItemMatching `json:"matching"`
}
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or sign in to comment