【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 天前
学习笔记:SKILLS 能帮助更好的vibe coding
笔记·学习
悠哉悠哉愿意3 天前
【单片机学习笔记】串口、超声波、NE555的同时使用
笔记·单片机·学习
别催小唐敲代码3 天前
嵌入式学习路线
学习
毛小茛3 天前
计算机系统概论——校验码
学习
babe小鑫3 天前
大专经济信息管理专业学习数据分析的必要性
学习·数据挖掘·数据分析
winfreedoms3 天前
ROS2知识大白话
笔记·学习·ros2
在这habit之下3 天前
Linux Virtual Server(LVS)学习总结
linux·学习·lvs
我想我不够好。3 天前
2026.2.25监控学习
学习
im_AMBER3 天前
Leetcode 127 删除有序数组中的重复项 | 删除有序数组中的重复项 II
数据结构·学习·算法·leetcode
CodeJourney_J3 天前
从“Hello World“ 开始 C++
c语言·c++·学习