今天花了一整天在做公司运营的的一个老电商平台的改造,很简单的一个商品搜索居然弄了一天才做好,需求背景是这样的,公司一个电商平台的之前一直是H5做的,最近受疫情影响,平台订单很多都发不了快递,所以公司趁这段时间正好再做一下电商平台的改造和升级,最近技术体系编程语言已经逐步从java转向golang,所以随带着对应的工具包也需要发生改变,本文就主要讲一下支撑商品搜索用bleve第三方包遇到的坑。
bleve是golang语言体系中最有影响力的全文检索包,在技术选型的时候查看了好几天的技术资料,比较了几个全文检索包之后最终选定的还是bleve,其中最看重的是有geo的检索接口,这个接口在后续做附近搜索时会用得到,所以斟酌再三就选择bleve做商品的全文检索了。
下边是bleve的索引和搜索的工具包代码,希望能帮到同行小伙伴。
package utils import ( "fmt" "os" "yurongMall/internal/model/entity" "github.com/blevesearch/bleve/v2" "github.com/gogf/gf/v2/util/gconv" ) type goods struct { Id int64 `json:"id"` Name string `json:"name"` Imgs string `json:"imgs"` Price string `json:"price"` } func SearchGoodsIndex(entity *entity.YrGoods) { mapping := bleve.NewIndexMapping() index, err := bleve.New("bleve.goods", mapping) if err != nil { fmt.Println(err) index, err = bleve.Open("bleve.goods") } defer index.Close() // index some data err = index.Index(gconv.String(entity.Id), entity) if err != nil { fmt.Println(err) return } } func SearchGoodsListIndex(list []entity.YrGoods) { os.RemoveAll("bleve.goods") mapping := bleve.NewIndexMapping() index, err := bleve.New("bleve.goods", mapping) if err != nil { fmt.Println(err) index, err = bleve.Open("bleve.goods") } defer index.Close() //index.FieldDict("name") // index some data for i := range list { goodsD := goods{ Id: list[i].Id, Name: list[i].Name, Imgs: list[i].Imgs, Price: list[i].Price, } fmt.Println(gconv.String(goodsD.Id) + "索引:" + goodsD.Name) err = index.Index(gconv.String(goodsD.Id), goodsD) } if err != nil { fmt.Println(err) return } } func SearchGoods(kw string, page int, size int) *bleve.SearchResult { index, err := bleve.Open("bleve.goods") if err != nil { fmt.Println(err) } defer index.Close() // search for some textm query := bleve.NewMatchQuery(kw) searchRequest := bleve.NewSearchRequest(query) searchRequest.From = (page - 1) * size searchRequest.Size = size searchRequest.Highlight = bleve.NewHighlight() //增加高亮显示后,在返回结果中才能有Fragments searchRequest.Highlight.AddField("name") //指定在Fragments中显示的内容 searchRequest.Highlight.AddField("imgs") searchRequest.Highlight.AddField("price") searchResults, err1 := index.Search(searchRequest) if err1 != nil { fmt.Println(err1) } return searchResults }
商品建立索引和搜索的函数如下:
func (c *cGoods) SearchGoods(ctx context.Context, req *v1.SearchGoodsListReq) (res *v1.Res, err error) { kv := g.RequestFromCtx(ctx).Get("kv").String() page := g.RequestFromCtx(ctx).Get("page").Int() limit := g.RequestFromCtx(ctx).Get("limit").Int() result := utils.SearchGoods(kv, page, limit) // for i := range result.Hits { // hit := result.Hits[i] // fmt.Println(hit.Fragments["name"]) // } g.RequestFromCtx(ctx).Response.WriteJson(result) return } func (c *cGoods) IndexGoods(ctx context.Context, req *v1.IndexGoodsReq) (res *v1.Res, err error) { list := service.GoodsService.GetGoodsList(ctx) utils.SearchGoodsListIndex(list) result := v1.Result{ Code: 200, Msg: "索引完成", Data: nil, } g.RequestFromCtx(ctx).Response.WriteJson(result) return }
先建立所有商品索引后,再搜索关键字即可显示对应的产品清单,并对关键词进行分词高亮显示。
2013-2024 LifeAdd生活方式 www.lifeadd.cn 版权所有 | 御融(北京)科技有限公司 All Rights
Reserved
增值电信业务经营许可证:京B2-20200664 | 京ICP备14004911号-7