golang elasticsearch入门教程 --- 202

2022-05-15  本文已影响0人  一位先生_

本教程从go语言角度讲解如何对elasticsearch进行增删改查。

目前golang操作elasticsearch的第三方包中最流行的是:

https://github.com/olivere/elastic

本教程也是基于elastic开发包进行讲解。

版本说明
golang的elastic开发包和elasticsearch版本有一些对应关系,在开发前需要注意下,必须选择正确的版本,下面是golang elastic开发包和elasticsearch版本关系表:

Elasticsearch version Go Elastic version go开发包地址
7.x 7.0 github.com/olivere/elastic/v7
6.x 6.0 github.com/olivere/elastic
5.x 5.0 gopkg.in/olivere/elastic.v5
例如:ES版本是7.0以后的版本,就使用github.com/olivere/elastic/v7这个包地址。

安装依赖包
本教程ES使用的是7.0以后的版本,因此安装GO的依赖包如下

go get github.com/olivere/elastic/v7

提示:如果使用goland作为ide,直接导入 import "github.com/olivere/elastic/v7" 包,goland会自动安装依赖包。

创建ES客户端
在操作ES之前需要创建一个client,用于操作ES,在创建client的时候需要提供ES连接参数。

package main

import "fmt"
import "github.com/olivere/elastic/v7"

func main() {
        // 创建ES client用于后续操作ES
    client, err := elastic.NewClient(
                // 设置ES服务地址,支持多个地址
        elastic.SetURL("http://127.0.0.1:9200", "http://127.0.0.1:9201"),
                // 设置基于http base auth验证的账号和密码
        elastic.SetBasicAuth("user", "secret"))
    if err != nil {
        // Handle error
        fmt.Printf("连接失败: %v\n", err)
    } else {
        fmt.Println("连接成功")
    }
}

创建索引

package main

import (
    "context"
    "fmt"
        "github.com/olivere/elastic/v7"
)

// 索引mapping定义,这里仿微博消息结构定义
const mapping = `
{
  "mappings": {
    "properties": {
      "user": {
        "type": "keyword"
      },
      "message": {
        "type": "text"
      },
      "image": {
        "type": "keyword"
      },
      "created": {
        "type": "date"
      },
      "tags": {
        "type": "keyword"
      },
      "location": {
        "type": "geo_point"
      },
      "suggest_field": {
        "type": "completion"
      }
    }
  }
}`

func main() {
        // 创建client
    client, err := elastic.NewClient(
        elastic.SetURL("http://127.0.0.1:9200", "http://127.0.0.1:9201"),
        elastic.SetBasicAuth("user", "secret"))
    if err != nil {
        // Handle error
        fmt.Printf("连接失败: %v\n", err)
    } else {
        fmt.Println("连接成功")
    }

    // 执行ES请求需要提供一个上下文对象
    ctx := context.Background()
    
    // 首先检测下weibo索引是否存在
    exists, err := client.IndexExists("weibo").Do(ctx)
    if err != nil {
        // Handle error
        panic(err)
    }
    if !exists {
        // weibo索引不存在,则创建一个
        _, err := client.CreateIndex("weibo").BodyString(mapping).Do(ctx)
        if err != nil {
            // Handle error
            panic(err)
        }
    }
}

提示:后续代码不再提重复提供完整的代码,直接引用client对象,则假定你已经完成包的加载和初始化client对象。

插入一条数据
先定义微博的struct, 跟前面创建的weibo索引结构一一对应。

type Weibo struct {
    User     string                `json:"user"` // 用户
    Message  string                `json:"message"` // 微博内容
    Retweets int                   `json:"retweets"` // 转发数
    Image    string                `json:"image,omitempty"` // 图片
    Created  time.Time             `json:"created,omitempty"` // 创建时间
    Tags     []string              `json:"tags,omitempty"` // 标签
    Location string                `json:"location,omitempty"` //位置
    Suggest  *elastic.SuggestField `json:"suggest_field,omitempty"`
}

上面struct定义的时候,都定义了json结构,因为ES请求使用的是json格式,在发送ES请求的时候,会自动转换成json格式。

使用struct结构插入一条ES文档数据,

// 创建创建一条微博

msg1 := Weibo{User: "olivere", Message: "打酱油的一天", Retweets: 0}

// 使用client创建一个新的文档
put1, err := client.Index().
        Index("weibo"). // 设置索引名称
        Id("1"). // 设置文档id
        BodyJson(msg1). // 指定前面声明的微博内容
        Do(ctx) // 执行请求,需要传入一个上下文对象
if err != nil {
        // Handle error
        panic(err)
    }

fmt.Printf("文档Id %s, 索引名 %s\n", put1.Id, put1.Index)
查询数据
// 根据id查询文档
get1, err := client.Get().
        Index("weibo"). // 指定索引名
        Id("1"). // 设置文档id
        Do(ctx) // 执行请求
if err != nil {
    // Handle error
    panic(err)
}
if get1.Found {
    fmt.Printf("文档id=%s 版本号=%d 索引名=%s\n", get1.Id, get1.Version, get1.Index)
}

# 手动将文档内容转换成go struct对象
msg2 := Weibo{}
// 提取文档内容,原始类型是json数据
data, _ := get1.Source.MarshalJSON()
// 将json转成struct结果
json.Unmarshal(data, &msg2)
// 打印结果
fmt.Println(msg2.Message)

更新数据
根据文档id更新内容

_, err := client.Update().
        Index("weibo"). // 设置索引名
        Id("1"). // 文档id
        Doc(map[string]interface{}{"retweets": 0}). // 更新retweets=0,支持传入键值结构
        Do(ctx) // 执行ES查询
if err != nil {
   // Handle error
   panic(err)
}
删除数据
// 根据id删除一条数据
_, err := client.Delete().
        Index("weibo").
        Id("1").
        Do(ctx)
if err != nil {
    // Handle error
    panic(err)
}
上一篇下一篇

猜你喜欢

热点阅读