【Go语言】elasticsearch的学习

一、es的连接

我这里使用的是云服务器上的es,所以在使用 Go 来进行连接的时候,我们需要将云服务器的IP地址知道,代码如下:

Go 复制代码
func EsConnect() {
	// 创建一个 Elasticsearch 客户端连接
	client, err := elastic.NewClient(
		elastic.SetURL("http://<your ip address>:9200"), // ES 服务地址
		elastic.SetSniff(false),                   // 禁用节点嗅探
	)
	if err != nil {
		log.Fatalf("Error creating the client: %s", err)
	}
	global.ESClient = client
}

二、索引操作

2.1 常见的类型

Go 复制代码
{
  "mappings": {
    "properties": {
      "title": { 
        "type": "text" // 查询的时候是分词匹配
      },
      "key": { 
        "type": "keyword" // 完整匹配
      },
      "user_id": {
        "type": "integer"
      },
      "created_at":{
        "type": "date",
        "null_value": "null",
        "format": "[yyyy-MM-dd HH:mm:ss]"
      }
    }
  }
}

2.2 创建索引

Go 复制代码
func CreateIndex() {
	createIndex, err := global.ESClient.CreateIndex("user_index").
        BodyString(models.UserModel{}.
        Mapping()).Do(context.Background())
	if err != nil {
		panic(err)
		return
	}
	fmt.Println(createIndex)
}

2.3 判断索引是否存在

Go 复制代码
// ExistsIndex 判断索引是否存在
func ExistsIndex(index string) bool {
  exists, _ := global.ESClient.
     IndexExists(index).Do(context.Background())
  return exists
}

2.4 删除索引

Go 复制代码
func DeleteIndex(index string) {
  _, err := global.ESClient.
    DeleteIndex(index).Do(context.Background())
  if err != nil {
    fmt.Println(err)
    return
  }
  fmt.Println(index, "索引删除成功")
}

三、文档操作

3.1 添加文档

3.1.1 添加单个文档

Go 复制代码
func DocCreate() {
  user := models.UserModel{
    ID:        12,
    UserName:  "lisi",
    Age:       23,
    NickName:  "夜空中最亮的lisi",
    CreatedAt: time.Now().Format("2006-01-02 15:04:05"),
    Title:     "今天天气很不错",
  }
  indexResponse, err :=         
     global.ESClient.Index().
     Index(user.Index()).
     BodyJson(user).Do(context.Background())
  if err != nil {
    fmt.Println(err)
    return
  }
  fmt.Printf("%#v\n", indexResponse)
}

我们在添加文档中,如果是 mapping 里面没有的字段,那么 es 会自动创建这个字段对应的 mapping。

3.1.2 批量添加文档

Go 复制代码
func DocCreateBatch() {

  list := []models.UserModel{
    {
      ID:        12,
      UserName:  "fengfeng",
      NickName:  "夜空中最亮的枫枫",
      CreatedAt: time.Now().Format("2006-01-02 15:04:05"),
    },
    {
      ID:        13,
      UserName:  "lisa",
      NickName:  "夜空中最亮的丽萨",
      CreatedAt: time.Now().Format("2006-01-02 15:04:05"),
    },
  }

  bulk := global.ESClient.Bulk().Index(models.UserModel{}.
        Index()).Refresh("true")
  for _, model := range list {
    req := elastic.NewBulkCreateRequest().Doc(model)
    bulk.Add(req)
  }
  res, err := bulk.Do(context.Background())
  if err != nil {
    fmt.Println(err)
    return
  }
  fmt.Println(res.Succeeded())
}

3.2 删除文档

3.2.1 根据id删除

Go 复制代码
func DocDelete() {

  deleteResponse, err := global.ESClient.Delete().
       Index(models.UserModel{}.Index()).Id("tmcqfYkBWS69Op6Q4Z0t").
       Refresh("true").Do(context.Background())
  if err != nil {
    fmt.Println(err)
    return
  }
  fmt.Println(deleteResponse)
}

如果我们要删除是文档不存在,我们会报 404 错误。

3.2.2 根据id批量删除

Go 复制代码
func DocDeleteBatch() {
  idList := []string{
    "tGcofYkBWS69Op6QHJ2g",
    "tWcpfYkBWS69Op6Q050w",
  }
  bulk := global.ESClient.Bulk().
    Index(models.UserModel{}.Index()).Refresh("true")
  for _, s := range idList {
    req := elastic.NewBulkDeleteRequest().Id(s)
    bulk.Add(req)
  }
  res, err := bulk.Do(context.Background())
  if err != nil {
    fmt.Println(err)
    return
  }
  fmt.Println(res.Succeeded())  // 实际删除的文档切片
}

如果我们需要删除的文档不存在,不会有错误,res.Succeeded() 为空。

3.3 文档查询

3.3.1 列表查询

Go 复制代码
func DocFind() {

  limit := 2
  page := 4
  from := (page - 1) * limit

  query := elastic.NewBoolQuery()
  res, err := global.ESClient.Search(models.UserModel{}.Index()).
    Query(query).From(from).Size(limit).Do(context.Background())
  if err != nil {
    fmt.Println(err)
    return
  }
  count := res.Hits.TotalHits.Value  // 总数
  fmt.Println(count)
  for _, hit := range res.Hits.Hits {
    fmt.Println(string(hit.Source))
  }
}

3.3.2 精确匹配

精确匹配是针对 keyword 字段,而不是针对 text 字段。

Go 复制代码
query := elastic.NewTermQuery("user_name", "fengfeng")

3.3.3 模糊匹配

主要是查 text,但是也可以查 keyword,模糊匹配 keyword 字段,是需要查完整的,匹配 text 字段则不用,搜完整的也会搜出很多。

Go 复制代码
query := elastic.NewMatchQuery("nick_name", "夜空中最亮的枫枫")

3.3.4 嵌套字段的搜索

Go 复制代码
"title": {
    "type": "text",
    "fields": {
        "keyword": {
            "type": "keyword",
            "ignore_above": 256
        }
    }
},

因为 title 是 text 类型,只能模糊匹配,但是需要精确匹配的时候,也能通过 title.keyword 的形式来进行精确匹配。

Go 复制代码
query := elastic.NewTermQuery("title.keyword", "这是我的枫枫") // 精确匹配
//query := elastic.NewMatchQuery("title", "这是我的枫枫")  // 模糊匹配

3.4 文档更新

Go 复制代码
func DocUpdate() {
  res, err := global.ESClient.Update().Index(models.UserModel{}.Index()).
    Id("vmdnfYkBWS69Op6QEp2Y").Doc(map[string]any{
    "user_name": "你好枫枫",
  }).Do(context.Background())
  if err != nil {
    fmt.Println(err)
    return
  }
  fmt.Printf("%#v\n", res)
}
相关推荐
南宫生3 小时前
力扣-图论-17【算法学习day.67】
java·学习·算法·leetcode·图论
sanguine__3 小时前
Web APIs学习 (操作DOM BOM)
学习
数据的世界016 小时前
.NET开发人员学习书籍推荐
学习·.net
四口鲸鱼爱吃盐6 小时前
CVPR2024 | 通过集成渐近正态分布学习实现强可迁移对抗攻击
学习
OopspoO8 小时前
qcow2镜像大小压缩
学习·性能优化
A懿轩A8 小时前
C/C++ 数据结构与算法【栈和队列】 栈+队列详细解析【日常学习,考研必备】带图+详细代码
c语言·数据结构·c++·学习·考研·算法·栈和队列
居居飒9 小时前
Android学习(四)-Kotlin编程语言-for循环
android·学习·kotlin
kkflash39 小时前
提升专业素养的实用指南
学习·职场和发展
1 9 J10 小时前
数据结构 C/C++(实验五:图)
c语言·数据结构·c++·学习·算法
6.9411 小时前
Scala——身份证号码查询籍贯
学习·scala