一.Golang 操作 ElasticSearch 的插件介绍
常见的 Golang 操作 ElasticSearch 的插件主要有下面两个:
第三方插件: github.com/olivere/elastic
官网插件 github.com/elastic/go-elasticsearch
其中 elastic 比 go-elasticsearch 文档更全面一些,start 量也更多一些,本节讲解 elastic
二.elastic 插件的使用
使用第三方库 https://github.com/olivere/elastic 来连接 ES 并进行操作
注意:
下载与 ES 相同版本的 client,例如这里使用的 ES 是 7.x 的版本,那么下
载的 client 也要与之对应为 github.com/olivere/elastic/v7
import (
... "github.com/olivere/elastic/v7"
)
官方实例代码参考:https://godoc.org/github.com/olivere/elastic
三.Gin 中使用 elastic 插件实现数据的增删改查
新建 models/esCore.go
引入elastic插件,先在esCore.go中import github.com/olivere/elastic/v7,然后在main.go文件下运行命令:go mod tidy即可; 注意:elastic版本要和ES版本对应
package models
//es插件使用
import (
"fmt"
"github.com/olivere/elastic/v7"
)
var EsClient *elastic.Client
func init() {
//注意IP和端口
EsClient, err = elastic.NewClient(elastic.SetURL("http://127.0.0.1:9200"))
if err != nil {
fmt.Println(err)
}
}
路由
在routers/frontendRouters.go中增加ElasticSearch相关路由
//设置es索引以及配置
defaultRouters.GET("/search", frontend.SearchController{}.Index)
//获取一条es数据
defaultRouters.GET("/search/getOne", frontend.SearchController{}.GetOne)
//增加数据到es中
defaultRouters.GET("/search/addGoods", frontend.SearchController{}.AddGoods)
//更新es中对应的数据
defaultRouters.GET("/search/updateGoods", frontend.SearchController{}.UpdateGoods)
//删除es中的数据
defaultRouters.GET("/search/deleteGoods", frontend.SearchController{}.DeleteGoods)
//模糊查询es数据
defaultRouters.GET("/search/query", frontend.SearchController{}.Query)
//条件筛选es查询
defaultRouters.GET("/search/filterQuery", frontend.SearchController{}.FilterQuery)
//分页查询es数据
defaultRouters.GET("/search/pagingQuery", frontend.SearchController{}.PagingQuery)
控制器相关代码
相关方法:
设置es索引以及配置,获取一条es数据,增加数据到es中,更新es中对应的数据,删除es中的数据,模糊查询es数据,条件筛选es查询,分页查询es数据
package frontend
//Elasticsearch 控制器
import (
"context"
"encoding/json"
"fmt"
"goshop/models"
"reflect"
"strconv"
"github.com/gin-gonic/gin"
"github.com/olivere/elastic/v7"
)
type SearchController struct {
BaseController
}
//初始化的时候判断索引goods是否存在,创建索引配置映射
func (con SearchController) Index(c *gin.Context) {
exists, err := models.EsClient.IndexExists("goods").Do(context.Background())
if err != nil {
// Handle error
fmt.Println(err)
}
print(exists)
if !exists {
// 配置映射
mapping := `
{
"settings": { //设置
"number_of_shards": 1, //分区数配置
"number_of_replicas": 0 //副本数配置
},
"mappings": { //映射
"properties": {
"Content": { //映射属性
"type": "text", //类型
"analyzer": "ik_max_word", // 检测粒度
"search_analyzer": "ik_max_word" //搜索粒度
},
"Title": {
"type": "text",
"analyzer": "ik_max_word",
"search_analyzer": "ik_max_word"
}
}
}
}
`
//注意:增加的写法-创建索引配置映射
_, err := models.EsClient.CreateIndex("goods").Body(mapping).Do(context.Background())
if err != nil {
// Handle error
fmt.Println(err)
}
}
c.String(200, "创建索引配置映射成功")
}
//增加商品数据到es
func (con SearchController) AddGoods(c *gin.Context) {
//获取数据库中的商品数据
goods := []models.Goods{}
models.DB.Find(&goods)
//循环商品,把每个商品存入es
for i := 0; i < len(goods); i++ {
_, err := models.EsClient.Index().
Index("goods"). //设置索引
Type("_doc"). //设置类型
Id(strconv.Itoa(goods[i].Id)). //设置id
BodyJson(goods[i]). //设置商品数据(结构体格式)
Do(context.Background())
if err != nil {
// Handle error
fmt.Println(err)
}
}
c.String(200, "AddGoods success")
}
//更新数据
func (con SearchController) UpdateGoods(c *gin.Context) {
goods := []models.Goods{}
models.DB.Find(&goods)
goods[0].Title = "我是修改后的数据"
goods[0].GoodsContent = "我是修改后的数据GoodsContent"
_, err := models.EsClient.Update().
Index("goods").
Type("_doc").
Id("19"). //要修改的数据id
Doc(goods[0]). //要修改的数据结构体
Do(context.Background())
if err != nil {
// Handle error
fmt.Println(err)
}
c.String(200, "修改数据 success")
}
//删除
func (con SearchController) DeleteGoods(c *gin.Context) {
_, err := models.EsClient.Delete().
Index("goods").
Type("_doc").
Id("19").
Do(context.Background())
if err != nil {
// Handle error
fmt.Println(err)
}
c.String(200, "删除成功 success")
}
//查询一条数据
func (con SearchController) GetOne(c *gin.Context) {
//defer 操作:捕获panic数据
defer func() {
if r := recover(); r != nil {
fmt.Println("Recovered in f", r)
c.String(200, "GetOne Error")
}
}()
result, err := models.EsClient.Get().
Index("goods").
Type("_doc").
Id("19").
Do(context.Background())
if err != nil { //判断数据是否存在,不存在则panic
// Some other kind of error
panic(err)
}
goods := models.Goods{} //实例化一个商品结构体
json.Unmarshal(result.Source, &goods) //把result结果解析到goods中
c.JSON(200, gin.H{
"goods": goods,
})
}
//模糊查询数据
func (con SearchController) Query(c *gin.Context) {
defer func() {
if r := recover(); r != nil {
fmt.Println("Recovered in f", r)
c.String(200, "Query Error")
}
}()
//模糊查询操作
query := elastic.NewMatchQuery("Title", "手机") //Title中包含 手机 的数据
searchResult, err := models.EsClient.Search().
Index("goods"). // search in index "goods"
Query(query). // specify the query
Do(context.Background()) // execute
if err != nil {
// Handle error
panic(err)
}
goods := models.Goods{}
c.JSON(200, gin.H{
"searchResult": searchResult.Each(reflect.TypeOf(goods)), //查询的结果:reflect.TypeOf(goods)类型断言,可以判断是否商品结构体
})
}
//分页查询
func (con SearchController) PagingQuery(c *gin.Context) {
defer func() {
if r := recover(); r != nil {
fmt.Println("Recovered in f", r)
c.String(200, "Query Error")
}
}()
page, _ := strconv.Atoi(c.Query("page")) //获取当前页码数
if page == 0 {
page = 1
}
pageSize := 2
query := elastic.NewMatchQuery("Title", "手机")
searchResult, err := models.EsClient.Search().
Index("goods"). // search in index "goods"
Query(query). // specify the query
Sort("Id", true). // true 表示升序 false 降序
From((page - 1) * pageSize).Size(pageSize). // 分页查询
Do(context.Background()) // execute
if err != nil {
// Handle error
panic(err)
}
goods := models.Goods{}
c.JSON(200, gin.H{
"searchResult": searchResult.Each(reflect.TypeOf(goods)),
})
}
//条件筛选查询
func (con SearchController) FilterQuery(c *gin.Context) {
defer func() {
if r := recover(); r != nil {
fmt.Println("Recovered in f", r)
c.String(200, "Query Error")
}
}()
//筛选
boolQ := elastic.NewBoolQuery()
boolQ.Must(elastic.NewMatchQuery("Title", "小米"))
boolQ.Filter(elastic.NewRangeQuery("Id").Gt(19)) //Id 大于19
boolQ.Filter(elastic.NewRangeQuery("Id").Lt(42)) //Id 小于42
searchResult, err := models.EsClient.Search().
Index("goods").
Type("_doc").
Sort("Id", true).
Query(boolQ).
Do(context.Background())
if err != nil {
fmt.Println(err)
}
goodsList := []models.Goods{}
var goods models.Goods
for _, item := range searchResult.Each(reflect.TypeOf(goods)) { //循环搜索结果,并把结果类型断言goods,如果结果类型是商品数据类型,则循环处理
t := item.(models.Goods)
fmt.Printf("Id:%v 标题:%v\n", t.Id, t.Title)
goodsList = append(goodsList, t)
}
c.JSON(200, gin.H{
"goodsList": goodsList,
})
}
[上一节][golang gin框架] 37.ElasticSearch 全文搜索引擎的使用文章来源:https://www.toymoban.com/news/detail-489044.html
[下一节][golang gin框架] 39.Gin商城项目-微服务实战之微服务架构文章来源地址https://www.toymoban.com/news/detail-489044.html
到了这里,关于[golang gin框架] 38.Gin操作Elasticsearch创建索引、修改映射、数据CURD以及数据分页的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!