HarmonyOS开发者限时福利来啦!最高10w+现金激励等你拿~ 了解详情
写点什么

go-elasticsearch: Elastic 官方的 Go 语言客户端

  • 2019-02-12
  • 本文字数:3403 字

    阅读完需:约 11 分钟

 go-elasticsearch: Elastic官方的Go语言客户端

说明

Elastic 官方鼓励在项目中尝试用这个包,但请记住以下几点:


  • 这个项目的工作还在进行中,并非所有计划的功能和 Elasticsearch 官方客户端中的标准(故障重试,节点自动发现等)都实现了。

  • API 稳定性无法保证。 尽管公共 API 的设计非常谨慎,但它们可以根据进一步的探索和用户反馈以不兼容的方式进行更改。

  • 客户端的目标是 Elasticsearch 7.x 版本。后续将添加对 6.x 和 5.x 版本 API 的支持。

安装

go get安装这个包:


go get -u github.com/elastic/go-elasticsearch
复制代码


或者将这个包添加到go.mod文件:


require github.com/elastic/go-elasticsearch v0.0.0
复制代码


或者克隆这个仓库:


git clone https://github.com/elastic/go-elasticsearch.git && cd go-elasticsearch
复制代码


一个完整的示例:


mkdir my-elasticsearch-app && cd my-elasticsearch-app
cat > go.mod <<-END module my-elasticsearch-app
require github.com/elastic/go-elasticsearch v0.0.0END
cat > main.go <<-END package main
import ( "log"
"github.com/elastic/go-elasticsearch" )
func main() { es, _ := elasticsearch.NewDefaultClient() log.Println(es.Info()) }END
go run main.go
复制代码

用法

elasticsearch包与另外两个包绑定在一起,esapi用于调用 Elasticsearch 的 API,estransport通过 HTTP 传输数据。


使用elasticsearch.NewDefaultClient()函数创建带有以下默认设置的客户端:


es, err := elasticsearch.NewDefaultClient()if err != nil {  log.Fatalf("Error creating the client: %s", err)}
res, err := es.Info()if err != nil { log.Fatalf("Error getting response: %s", err)}
log.Println(res)
// [200 OK] {// "name" : "node-1",// "cluster_name" : "go-elasticsearch"// ...
复制代码


注意:当导出ELASTICSEARCH_URL环境变量时,它将被用作集群端点。


使用elasticsearch.NewClient()函数(仅用作演示)配置该客户端:


cfg := elasticsearch.Config{  Addresses: []string{    "http://localhost:9200",    "http://localhost:9201",  },  Transport: &http.Transport{    MaxIdleConnsPerHost:   10,    ResponseHeaderTimeout: time.Second,    DialContext:           (&net.Dialer{Timeout: time.Second}).DialContext,    TLSClientConfig: &tls.Config{      MaxVersion:         tls.VersionTLS11,      InsecureSkipVerify: true,    },  },}
es, err := elasticsearch.NewClient(cfg)// ...
复制代码


下面的示例展示了更复杂的用法。它从集群中获取 Elasticsearch 版本,同时索引几个文档,并使用响应主体周围的一个轻量包装器打印搜索结果。


// $ go run _examples/main.go
package main
import ( "context" "encoding/json" "log" "strconv" "strings" "sync"
"github.com/elastic/go-elasticsearch" "github.com/elastic/go-elasticsearch/esapi")
func main() { log.SetFlags(0)
var ( r map[string]interface{} wg sync.WaitGroup )
// Initialize a client with the default settings. // // An `ELASTICSEARCH_URL` environment variable will be used when exported. // es, err := elasticsearch.NewDefaultClient() if err != nil { log.Fatalf("Error creating the client: %s", err) }
// 1. Get cluster info // res, err := es.Info() if err != nil { log.Fatalf("Error getting response: %s", err) } // Deserialize the response into a map. if err := json.NewDecoder(res.Body).Decode(&r); err != nil { log.Fatalf("Error parsing the response body: %s", err) } // Print version number. log.Printf("~~~~~~~> Elasticsearch %s", r["version"].(map[string]interface{})["number"])
// 2. Index documents concurrently // for i, title := range []string{"Test One", "Test Two"} { wg.Add(1)
go func(i int, title string) { defer wg.Done()
// Set up the request object directly. req := esapi.IndexRequest{ Index: "test", DocumentID: strconv.Itoa(i + 1), Body: strings.NewReader(`{"title" : "` + title + `"}`), Refresh: "true", }
// Perform the request with the client. res, err := req.Do(context.Background(), es) if err != nil { log.Fatalf("Error getting response: %s", err) } defer res.Body.Close()
if res.IsError() { log.Printf("[%s] Error indexing document ID=%d", res.Status(), i+1) } else { // Deserialize the response into a map. var r map[string]interface{} if err := json.NewDecoder(res.Body).Decode(&r); err != nil { log.Printf("Error parsing the response body: %s", err) } else { // Print the response status and indexed document version. log.Printf("[%s] %s; version=%d", res.Status(), r["result"], int(r["_version"].(float64))) } } }(i, title) } wg.Wait()
log.Println(strings.Repeat("-", 37))
// 3. Search for the indexed documents // // Use the helper methods of the client. res, err = es.Search( es.Search.WithContext(context.Background()), es.Search.WithIndex("test"), es.Search.WithBody(strings.NewReader(`{"query" : { "match" : { "title" : "test" } }}`)), es.Search.WithTrackTotalHits(true), es.Search.WithPretty(), ) if err != nil { log.Fatalf("ERROR: %s", err) } defer res.Body.Close()
if res.IsError() { var e map[string]interface{} if err := json.NewDecoder(res.Body).Decode(&e); err != nil { log.Fatalf("error parsing the response body: %s", err) } else { // Print the response status and error information. log.Fatalf("[%s] %s: %s", res.Status(), e["error"].(map[string]interface{})["type"], e["error"].(map[string]interface{})["reason"], ) } }
if err := json.NewDecoder(res.Body).Decode(&r); err != nil { log.Fatalf("Error parsing the response body: %s", err) } // Print the response status, number of results, and request duration. log.Printf( "[%s] %d hits; took: %dms", res.Status(), int(r["hits"].(map[string]interface{})["total"].(map[string]interface{})["value"].(float64)), int(r["took"].(float64)), ) // Print the ID and document source for each hit. for _, hit := range r["hits"].(map[string]interface{})["hits"].([]interface{}) { log.Printf(" * ID=%s, %s", hit.(map[string]interface{})["_id"], hit.(map[string]interface{})["_source"]) }
log.Println(strings.Repeat("=", 37))}
// ~~~~~~~> Elasticsearch 7.0.0-SNAPSHOT// [200 OK] updated; version=1// [200 OK] updated; version=1// -------------------------------------// [200 OK] 2 hits; took: 7ms// * ID=1, map[title:Test One]// * ID=2, map[title:Test Two]// =====================================
复制代码


如上述示例所示,esapi包允许通过两种不同的方式调用 Elasticsearch API:通过创建结构(如IndexRequest),并向其传递上下文和客户端来调用其Do()方法,或者通过客户端上可用的函数(如WithIndex())直接调用其上的Search()函数。更多信息请参阅包文档。


estransport包处理与 Elasticsearch 之间的数据传输。 目前,这个实现只占据很小的空间:它只在已配置的集群端点上进行循环。后续将添加更多功能:重试失败的请求,忽略某些状态代码,自动发现群集中的节点等等。

Examples

_examples文件夹包含许多全面的示例,可帮助你上手使用客户端,包括客户端的配置和自定义,模拟单元测试的传输,将客户端嵌入自定义类型,构建查询,执行请求和解析回应。

许可证

遵循 Apache License 2.0 版本。


参考链接:


https://github.com/elastic/go-elasticsearch#go-elasticsearch


2019-02-12 08:0016542
用户头像
张婵 InfoQ 技术编辑

发布了 87 篇内容, 共 53.0 次阅读, 收获喜欢 218 次。

关注

评论 1 条评论

发布
用户头像
感谢怕大家看不懂将README翻译了一次系列 o(╯□╰)o
2019-08-01 10:36
回复
没有更多了
发现更多内容

Vue进阶(幺陆陆):组件实例 $el 详解

No Silver Bullet

Vue 7月日更 $el

详解Java内存模型

程序员阿杜

Java JVM Java虚拟机

面试官:聊聊JVM吧?

程序员阿杜

Java JVM JVM原理

java 虐“狗”日常

喵叔

7月日更

极客时间-大数据-作业三-HBase 创建表

西伯利亚鼯鼠

在线生成制作Pornhub的微信公众号封面图

入门小站

工具

35岁以后的Java程序员出路在哪里?最全的BAT大厂面试题整理

策划Java工程师

Java 程序员 面试 后端

架构实战营 模块 4 作业

Geek_8c5f9c

架构实战营

2021最新网易Java面经,面试必会

Java 程序员 面试 后端

34岁Java开发大叔感慨,100%好评!

策划Java工程师

Java 程序员 面试 后端

350道Java面试真题分享,王者笔记!

策划Java工程师

Java 程序员 面试 后端

2021最新华为Java校招面试题,看完直呼内行

Java 程序员 面试 后端

2021网易Java高级面试题总结,面试篇

Java 程序员 面试 后端

2021谈一下当下最合适的Java架构,感悟分享

Java 程序员 面试 后端

来自跨越边界的急件,我推荐你用这三步,走出锁住你的圈套。

叶小鍵

外包学生管理系统的架构设计

架构0期-Bingo

25K大牛甩出的超详细面试总结,砥砺前行!

策划Java工程师

Java 程序员 面试 后端

35岁程序员半月4轮面试,HR的话扎心了

策划Java工程师

Java 程序员 面试 后端

【Flutter 专题】131 图解 AnimatedList 动画列表

阿策小和尚

Flutter 小菜 0 基础学习 Flutter Android 小菜鸟 8月日更

2021谈一下当下最合适的Java架构,神操作!

Java 程序员 面试 后端

网络攻防学习笔记 Day91

穿过生命散发芬芳

网络攻防 7月日更

2021最新Java高频精选面试题讲解,绝对干货

Java 程序员 面试 后端

2021最新阿里Java面经,一篇文章帮你解答

Java 程序员 面试 后端

25K大牛甩出的超详细面试总结,已获万赞

策划Java工程师

Java 程序员 面试 后端

Vue进阶(幺柒柒):Vue 应用 Sass、Scss、Less 和 Stylus

No Silver Bullet

Vue 7月日更 预处理器

Linux之vmstat命令

入门小站

Linux

2021最新腾讯Java高级面试题总结,Java篇

Java 程序员 面试 后端

35岁的程序员被裁,电子版已问世

策划Java工程师

Java 程序员 面试 后端

35岁程序员半月4轮面试,项目实战

策划Java工程师

Java 程序员 面试 后端

20道高频面试题(含答案),看完豁然开朗

Java 程序员 面试 后端

35岁的程序员被裁,90%的人看完都说好

策划Java工程师

Java 程序员 面试 后端

 go-elasticsearch: Elastic官方的Go语言客户端_语言 & 开发_张婵_InfoQ精选文章