百度360必应搜狗淘宝本站头条
当前位置:网站首页 > 编程文章 > 正文

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

qiyuwang 2024-10-04 05:03 10 浏览 0 评论

说明

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.0
END
 
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

相关推荐

别再乱找了!这才是 Alist 本地安装挂载的正确打开方式

一、探秘Alist的神奇世界在这个数据爆炸的时代,我们的生活里充斥着各种各样的网盘服务,百度网盘、阿里云盘、腾讯微云等等,它们成了我们存储资料的得力助手。但随着网盘数量的增多,管理这些分散在不同平...

如何将数据从旧iPhone传输到新iPhone 16?这五个方法你必须知道!

前不久,苹果发布了备受期待的iPhone16系列,新机型搭载了更强大的芯片、更流畅的操作体验,还有备受热议的全新摄像系统。无论你是冲着A18仿生芯片,还是更丰富的动态岛功能,相信很多果粉早已跃跃欲试...

大数据传输的定义与大数据传输解决方案的选择

当我们需要处理大量的数据时,我们就要把数据从一个地方移动到另一个地方。这个过程就叫做大数据传输。它通常需要用到高速的网络连接、分散的存储系统和数据传输协议,以保证数据的快速、可靠和安全的移动。常用的大...

【工具】在线传输文件工具(在线文件互传)

前言在线传输文件工具主要是用于在不同的设备之间,如手机、电脑、平板等快速便捷地传送文件。告别使用USB传统传输文件的方式。...

如何使用 CAN-FD 在 LPC5500 上传输数据

目录1引言2CAN-FD3示例演示1引言...

轻松同步:将照片从三星手机传输到iPad的简便方法

概括想要在新iPad上查看三星照片吗?但是,如果您不知道如何将照片从三星手机传输到iPad,则无法在iPad上查看图片。为此,本文分享了7个有用的方法,以便您可以使用它们在不同操作系统之...

常见又地道的网络缩写:美剧中常说的SFW到底是个啥?

在这堂课中,让我们来学习更多在数字网络世界中常用的有趣网络用语。7shifts/unsplashhttp,https“http”和“https”是万维网(www)传输文件用的协议。“http”是hy...

每天学会一个计算机网络协议之FTP

开始行文之前提出一个问题,相信大家在看完本文后一定可以回答当我们在网站上填写注册信息的时候,需要我们上传照片,上传的过程发生了什么?下面引入我们的主角,FTP文件传输协议FTPFileTransf...

即用即走,这3款文件分享工具真香

打工人的日常,免不了「文件分享存储服务」的需求。我们一般会选择不同的网盘,但是大家也知道,网盘不是限速就是叫你充值。今天跟大家简单推荐3款文件分享工具,既可以免登录匿名使用,而且操作简单稳定性也不错。...

安卓手机里的文件和照片与Mac互传的办法

因为HandShake一段时间未更新,似乎目前不可操作。我一时间未找到更好的「传输」办法,经实践操作,向大家介绍一下「安卓手机」,包括「一加」、「索尼」,都可用此方法,来进行文件传输到Mac的...

软网推荐:同一个平台选择不同的传输方法

平时上网的时候,我们经常要分享一些文件给其他朋友,一般通过云服务平台来实现。今天笔者给大家介绍的Worksphere传输服务,它提供了两种不同的分享方式,方便我们根据实际需要进行选择。一个链接分享所有...

跨平台不限速的免费文件传输网站(跨平台不限速的免费文件传输网站是什么)

大家好,欢迎来到天天惠分享,不知道各位平时都是用什么方法来进行文件跨平台传输的呢?是百度网盘?微信还是QQ?亦或是有线传输。虽然这些方法都可以达到传输的目的,但都有各自的缺陷,使用起来一言难尽。比如百...

全网最全最详细的全平台文件传输方法,解决你文件传输问题(一)

前言想必现在大多数人文件传输的方法还是使用qq微信,但是qq微信的文件传输有时候真是,...

文件传输工具有哪些?这3款堪称办公必备!

在不同设备间,想把文件从一台设备传输到另一台,尤其是大体积文件,更是免不了用到文件传输工具,可以说文件传输工具已成为提升效率的关键载体。面对海量文档、设计素材、会议纪要的流转需求,传统邮件附件、U盘拷...

小白也能用的跨网文件交换系统!10款简单易上手的文件摆渡工具

跨网文件交换系统对于需要频繁在不同网络环境中进行文件共享的用户来说至关重要。以下是10款简单易上手的文件摆渡工具,适合小白用户使用,帮助他们高效地分享和传输文件。10款简单易上手的跨网文件交换工具1....

取消回复欢迎 发表评论: