在网上看了一些,具体的有两种,一种是 github.com/olivere/elastic *** 作,还有一种用的是 github.com/elastic/go-elasticsearch ,后一中好像用的少,但是不巧的是我用的就是后一种。
查询的条件语句很好拼,但是不会在golang中用,在golang中 *** 作的基本上都是用map[string]interface{}拼接然后转json,类似于这种:
query := map[string]interface{}{
"query": map[string]interface{}{
"bool": map[string]interface{}{
"filter": map[string]interface{}{
"multi_match": map[string]interface{}{
"query": key.KeyWord,
"fields": []string{"produceCompany", "productName"},
},
},
},
},
}
body, _ := json.Marshal(&query)
作为小白,那就找到啥用啥,但是有个问题,就是我的es语句是带有 “[ ]”的,没办法用map[string]interface{},为此我还苦恼了两三天找不到怎么在interface{}中加[ ]的办法。然后有一位新来的大佬说,既然都是转json,那就用结构体转吧。然后,问题就解决了。idea有自带的json转struct,可以直接复制json语句粘贴,自己就转了。非常好用
然后就是查找,根据条件拼接es语句,拼起来转为json,实现查找
func (s *SearchService) GetCollection(ctx context.Context, key *request.CollectionReq) (interface{}, error) {
//各个条件判断
var filter []interface{}
if key.CollectionType != 0 {
var auto search.AutoCollectionType
auto.Bool.Must.Match.CollectionType = key.CollectionType
filter = append(filter, auto)
}
if key.ProductCategory != 0 {
var auto search.AutoProductCategory
auto.Bool.Must.Match.ProductCategory = key.ProductCategory
filter = append(filter, auto)
}
if key.ProvinceCode != "" {
var auto search.AutoProvinceCode
auto.Bool.Must.Match.ProvinceCode = key.ProvinceCode
filter = append(filter, auto)
}
if key.CityCode != "" {
var auto search.AutoCityCode
auto.Bool.Must.Match.CityCode = key.CityCode
filter = append(filter, auto)
}
if key.TerminalType != "" {
var auto search.AutoTerminalType
auto.Bool.Must.Match.TerminalType = key.TerminalType
filter = append(filter, auto)
}
if key.CreatedAtStart != "" {
var auto search.AutoCreate
auto.Bool.Must.Range.CreatedAt.Gte = key.CreatedAtStart
auto.Bool.Must.Range.CreatedAt.Lte = key.CreatedAtEnd
filter = append(filter, auto)
}
if key.KeyWord != "" {
var auto search.AutoKeyWord
auto.Bool.Must.MultiMatch.Fields = []string{"produceCompany", "productName", "title", "terminalName"}
auto.Bool.Must.MultiMatch.Query = key.KeyWord
filter = append(filter, auto)
}
//获取查询的query
query := search.EsQuery{
Query: struct {
Bool struct {
Filter []interface{} `json:"filter"`
} `json:"bool"`
}{},
}
query.Query.Bool.Filter = filter
//转json
body, _ := json.Marshal(&query)
req := esapi.SearchRequest{
Index: []string{CollSchemaName}, //es对应的_index
DocumentType: []string{CollSchemaName}, //es对应的_type
Body: bytes.NewReader(body), //查询的结构体
Size: &key.PageSize, //分页
From: &key.Page,
Source: []string{"id"}, //只查id
}
res, err := req.Do(ctx, s.Client) //s.Client是 elasticsearch.Client的
if err != nil {
global.GVA_LOG.Error(err.Error())
}
if res.StatusCode > 300 {
global.GVA_LOG.Error("es 查询错误,错误信息:" + res.String())
return nil, err
}
//查询结果res,类型为io.ReadCloser,转为json
buff := new(bytes.Buffer)
_, err = buff.ReadFrom(res.Body)
if err != nil {
return nil, err
}
buffBytes := buff.Bytes()
//json 转 struct
buffJson := response.CollectionRespElastic{}
_ = json.Unmarshal(buffBytes, &buffJson)
var ids []string
for _, val := range buffJson.Hits.Hits {
ids = append(ids, val.Id)
}
defer res.Body.Close()
//数据库查找(因为es库存的是搜索的关键信息,所以最后还是要从mysql查)
if key.CollectionType == 1 {
var list []*respBusiness.CollectionDetailResp
err = global.GVA_DB.Table("v_collection_detail").Where("id in ?", ids).Find(&list).Error
return list, err
} else if key.CollectionType == 2 {
var list []*respBusiness.CollResp
err = global.GVA_DB.Model(&respBusiness.CollResp{}).Where("id in ?", ids).Find(&list).Error
return list, err
}
return nil, err
}
从es查出来的数据也是同样的map[string]interface{}的结构,查出来的东西都在hits[ ]中,之前钻牛角尖,妄图在map[string]interface{}中把hits[ ] 取出来,转念一想,还是用struct方便
{
"took": 0,
"timed_out": false,
"_shards": {
"total": 5,
"successful": 5,
"skipped": 0,
"failed": 0
},
"hits": {
"total": 80,
"max_score": 1.0,
"hits": []
}
}
一样的思路,用结构体接收,用不到的就直接interface{},用到的就定义,json一定要对应好,定义之后取用就很方便
type CollectionRespElastic struct {
Took int `json:"took"`
TimedOut bool `json:"timed_out"`
Shards interface{} `json:"_shards"`
Hits *Hits `json:"hits"`
}
type Hits struct {
Total int `json:"total"`
MaxScore int `json:"max_score"`
Hits []*Hitss `json:"hits"`
}
type Hitss struct {
Index string `json:"_index"`
Type string `json:"_type"`
Id string `json:"_id"`
Soure int `json:"_score"`
Source interface{} `json:"_source"`
}
有个小问题,就是es 查询不支持查“空”字段,比如collectionMode字段类型是text,但是没有存数据,查看全部显示的是 " " ,但是如果你在查询条件中写{ "collectionMode":" " }这样就会报错
欢迎分享,转载请注明来源:内存溢出
评论列表(0条)