前言
ZincSearch官网及开发文档都是英文的,英文对于英文不好及不常用英文的开发朋友不太友好,因此GoFly全栈开发社区花点时间把官方的英文文档翻译成中文,并在文档中增加了我们实战中有的知识点英文文档没有写的内容已经我们使用时的实战代码,丰富了文档,这样新手朋友可以少折腾点。
相关文档
官网英文文档:https://zincsearch-docs.zinc.dev
GoFly翻译完善的中文文档:ZincSearch搜索引擎中文文档
Go语言中代码实现
首先说明一下ZincSearch是采用RESTful API 使用 HTTP 作为传输协议,使用 JSON 作为数据交换格式. 所有的语言都可以使用 RESTful API,这样可支持多种语言,比如有Java 、C#、PHP、Go等。因为我们使用Go作为开发语言,所以这里就讲Go语言使用。
1.封装工具库
在zincsearch插件包中我们先创建一个文件用来编写工具库,取名为util.go,工具有获取完整请求路径和http请求方法,代码为:
package zincsearch import ( "fmt" "gofly/utils/gf" "gofly/utils/tools/gbase64" "gofly/utils/tools/gconv" "io" "net/http" "strings" ) var ( cosdata, _ = gf.GetConfByFile("zincsearch") CosConf = gconv.Map(gconv.Map(cosdata)["data"]) ) // 获取完整请求路径 func GetUrl(path string) string { return fmt.Sprintf("%v%v", CosConf["url"], path) } // http请求 // method=请求方式(GET POST PUT DELETE),url=请求地址,data请求数据 func RequestHttp(method, url, data string) (string, error) { payload := strings.NewReader(data) client := &http.Client{} req, err := http.NewRequest(method, url, payload) if err != nil { return "", err } req.Header.Add("Content-Type", "application/json") req.Header.Add("Authorization", "Basic "+gbase64.EncodeString(fmt.Sprintf("%v:%v", CosConf["username"], CosConf["password"]))) resp, err := client.Do(req) if err != nil { return "", err } defer resp.Body.Close() body, err := io.ReadAll(resp.Body) if err != nil { return "", err } return string(body), nil }
2.封装ZincSearch操作接口
这里就用创建索引、更新索引、删除索引、获取索引为例,其他的文档、搜索接口参考来写接口,创建Index.go文件,代码如下:
package zincsearch import ( "encoding/json" "fmt" "strconv" ) type Index struct { ShardNum int //分片数 PageNum int //页数 PageSize int //条数 SortBy string //排序字段 Desc bool //按降序排序 Name string //通过名称进行模糊查询 } // 1.插入索引数据 // 参数:indexname=索引名称,fields=索引的字段信息(key-value数组) func (api *Index) Insert(indexname string, fields interface{}) (res string, err error) { var properties []byte properties, err = json.Marshal(fields) if err != nil { return } weburl := GetUrl("/api/index") data := `{ "name": "` + indexname + `", "storage_type": "disk", "shard_num": ` + strconv.Itoa(api.ShardNum) + `, "mappings": { "properties":` + string(properties) + ` } }` res, err = RequestHttp("POST", weburl, data) return } // 2.更新索引数据 // 参数:indexname=索引名称,fields=索引的字段信息(key-value数组) func (api *Index) Update(indexname string, fields interface{}) (res string, err error) { var properties []byte properties, err = json.Marshal(fields) if err != nil { return } weburl := GetUrl("/api/index") data := `{ "name": "` + indexname + `", "storage_type": "disk", "shard_num": ` + strconv.Itoa(api.ShardNum) + `, "mappings": { "properties":` + string(properties) + ` } }` res, err = RequestHttp("PUT", weburl, data) return } // 3.删除索引数据 // 参数:indexname=索引名称 func (api *Index) Del(indexname string) (res string, err error) { weburl := GetUrl(fmt.Sprintf("/api/index/%v", indexname)) res, err = RequestHttp("DELETE", weburl, "") return } // 4.列出当前已经存在的索引 func (api *Index) List() (res string, err error) { pathurl := fmt.Sprintf("/api/index?page_num=%v&page_size=%v&sort_by=%v&desc=%v", api.PageNum, api.PageSize, api.SortBy, api.Desc) if api.Name != "" { pathurl += fmt.Sprintf("&name=%v", api.Name) } weburl := GetUrl(pathurl) res, err = RequestHttp("GET", weburl, "") return } // 设置分片数-并行读取的能力,默认1 func (api *Index) SetShardNum(num int) *Index { api.ShardNum = num return api } // 设置分页数据 func (api *Index) Page(page, pagesize int) *Index { api.PageNum = page api.PageSize = pagesize return api } // 设置排序字段,单个字段,如:name,默认name func (api *Index) OrderField(field string) *Index { api.SortBy = field return api } // 是否降序排序,默认:false func (api *Index) IsDesc() *Index { api.Desc = true return api } // 通过名称进行模糊查询 func (api *Index) FindName(name string) *Index { api.Name = name return api }
3.统一组件调用
为了方便在业务代码中使用组件封装的ZincSearch功能对应接口,我们创建zincsearch.go来做统一调用入口,这样可以规范组件代码风格,方便编写及代码维护。zincsearch.go代码如下:
package plugin import ( "gofly/utils/plugin/zincsearch" ) // ZincSearch全文搜索接口 type Zincs struct{} // ZincSearch接口实例 func ZincSearch() *Zincs { return &Zincs{} } // 1.索引接口 func (*Zincs) Index() *zincsearch.Index { return &zincsearch.Index{ShardNum: 1, PageNum: 1, SortBy: "name", Desc: false} } // 2.文档接口 //func (*Zincs) Doc() *zincsearch.Doc { // return &zincsearch.Doc{} //} // 3.基础搜索接口 //func (*Zincs) Search() *zincsearch.Search { // return &zincsearch.Search{From: 0, Size: 10} //} // 4.ES搜索接口 //func (*Zincs) EsSearch() *zincsearch.EsSearch { // return &zincsearch.EsSearch{From: 0, Size: 10} //}
4.业务代码中使用
gofly框架在业务开发位置调用很简单,在import中引入gofly/utils/plugin扩展。
- 在使用的位置引入插件
引入代码如下:
import ( "gofly/utils/plugin" )
- 调用方法
调用代码格式:plugin.ZincSearch().xx().方法(),例如:
res, err := plugin.ZincSearch().Index().Insert("indexname", "fields")
- 实例代码
把我们测试用的示例代码ZincSearch.go完整代码提供给大家做个参考,GoFly框架使用完整代码如下:
package createcode import ( "gofly/utils/gf" "gofly/utils/plugin" ) // 测试ZincSearch全文搜索引擎接口 type ZincSearch struct{} func init() { fpath := ZincSearch{} gf.Register(&fpath, fpath) } // 添加索引 func (api *ZincSearch) AddIndex(c *gf.GinCtx) { param, _ := gf.RequestParam(c) res, err := plugin.ZincSearch().Index().Insert(gf.String(param["name"]), param["fields"]) if err != nil { gf.Failed().SetMsg("添加索引失败").SetData(err).Regin(c) return } gf.Success().SetMsg("添加索引成功").SetData(res).Regin(c) } // 获取索引 func (api *ZincSearch) GetList(c *gf.GinCtx) { param, _ := gf.RequestParam(c) list, err := plugin.ZincSearch().Index().Page(1, 10).FindName(gf.String(param["name"])).List() if err != nil { gf.Failed().SetMsg("添加索引失败").SetData(err).Regin(c) return } gf.Success().SetMsg("添加索引成功").SetData(list).Regin(c) }
ZincSearch搜索引擎中文文档和在Go语言中实践简介绍到这。