Elastic官方鼓励在项目中尝试用这个包,但请记住以下几点:
\n用go get
安装这个包:
go get -u github.com/elastic/go-elasticsearch\n
\n
或者将这个包添加到go.mod
文件:
require github.com/elastic/go-elasticsearch v0.0.0\n
\n
或者克隆这个仓库:
\ngit clone https://github.com/elastic/go-elasticsearch.git \u0026amp;\u0026amp; cd go-elasticsearch\n
\n
一个完整的示例:
\nmkdir my-elasticsearch-app \u0026amp;\u0026amp; cd my-elasticsearch-app\n\ncat \u0026gt; go.mod \u0026lt;\u0026lt;-END\n module my-elasticsearch-app\n\n require github.com/elastic/go-elasticsearch v0.0.0\nEND\n\ncat \u0026gt; main.go \u0026lt;\u0026lt;-END\n package main\n\n import (\n \u0026quot;log\u0026quot;\n\n \u0026quot;github.com/elastic/go-elasticsearch\u0026quot;\n )\n\n func main() {\n es, _ := elasticsearch.NewDefaultClient()\n log.Println(es.Info())\n }\nEND\n\ngo run main.go\n
\n
elasticsearch
包与另外两个包绑定在一起,esapi
用于调用Elasticsearch的API,estransport
通过HTTP传输数据。
使用elasticsearch.NewDefaultClient()
函数创建带有以下默认设置的客户端:
es, err := elasticsearch.NewDefaultClient()\nif err != nil {\n log.Fatalf(\u0026quot;Error creating the client: %s\u0026quot;, err)\n}\n\nres, err := es.Info()\nif err != nil {\n log.Fatalf(\u0026quot;Error getting response: %s\u0026quot;, err)\n}\n\nlog.Println(res)\n\n// [200 OK] {\n// \u0026quot;name\u0026quot; : \u0026quot;node-1\u0026quot;,\n// \u0026quot;cluster_name\u0026quot; : \u0026quot;go-elasticsearch\u0026quot;\n// ...\n
\n
注意:当导出ELASTICSEARCH_URL
环境变量时,它将被用作集群端点。
使用elasticsearch.NewClient()
函数(仅用作演示)配置该客户端:
cfg := elasticsearch.Config{\n Addresses: []string{\n \u0026quot;http://localhost:9200\u0026quot;,\n \u0026quot;http://localhost:9201\u0026quot;,\n },\n Transport: \u0026amp;http.Transport{\n MaxIdleConnsPerHost: 10,\n ResponseHeaderTimeout: time.Second,\n DialContext: (\u0026amp;net.Dialer{Timeout: time.Second}).DialContext,\n TLSClientConfig: \u0026amp;tls.Config{\n MaxVersion: tls.VersionTLS11,\n InsecureSkipVerify: true,\n },\n },\n}\n\nes, err := elasticsearch.NewClient(cfg)\n// ...\n
\n
下面的示例展示了更复杂的用法。它从集群中获取Elasticsearch版本,同时索引几个文档,并使用响应主体周围的一个轻量包装器打印搜索结果。
\n// $ go run _examples/main.go\n\npackage main\n\nimport (\n \u0026quot;context\u0026quot;\n \u0026quot;encoding/json\u0026quot;\n \u0026quot;log\u0026quot;\n \u0026quot;strconv\u0026quot;\n \u0026quot;strings\u0026quot;\n \u0026quot;sync\u0026quot;\n\n \u0026quot;github.com/elastic/go-elasticsearch\u0026quot;\n \u0026quot;github.com/elastic/go-elasticsearch/esapi\u0026quot;\n)\n\nfunc main() {\n log.SetFlags(0)\n\n var (\n r map[string]interface{}\n wg sync.WaitGroup\n )\n\n // Initialize a client with the default settings.\n //\n // An `ELASTICSEARCH_URL` environment variable will be used when exported.\n //\n es, err := elasticsearch.NewDefaultClient()\n if err != nil {\n log.Fatalf(\u0026quot;Error creating the client: %s\u0026quot;, err)\n }\n\n // 1. Get cluster info\n //\n res, err := es.Info()\n if err != nil {\n log.Fatalf(\u0026quot;Error getting response: %s\u0026quot;, err)\n }\n // Deserialize the response into a map.\n if err := json.NewDecoder(res.Body).Decode(\u0026amp;r); err != nil {\n log.Fatalf(\u0026quot;Error parsing the response body: %s\u0026quot;, err)\n }\n // Print version number.\n log.Printf(\u0026quot;~~~~~~~\u0026gt; Elasticsearch %s\u0026quot;, r[\u0026quot;version\u0026quot;].(map[string]interface{})[\u0026quot;number\u0026quot;])\n\n // 2. Index documents concurrently\n //\n for i, title := range []string{\u0026quot;Test One\u0026quot;, \u0026quot;Test Two\u0026quot;} {\n wg.Add(1)\n\n go func(i int, title string) {\n defer wg.Done()\n\n // Set up the request object directly.\n req := esapi.IndexRequest{\n Index: \u0026quot;test\u0026quot;,\n DocumentID: strconv.Itoa(i + 1),\n Body: strings.NewReader(`{\u0026quot;title\u0026quot; : \u0026quot;` + title + `\u0026quot;}`),\n Refresh: \u0026quot;true\u0026quot;,\n }\n\n // Perform the request with the client.\n res, err := req.Do(context.Background(), es)\n if err != nil {\n log.Fatalf(\u0026quot;Error getting response: %s\u0026quot;, err)\n }\n defer res.Body.Close()\n\n if res.IsError() {\n log.Printf(\u0026quot;[%s] Error indexing document ID=%d\u0026quot;, res.Status(), i+1)\n } else {\n // Deserialize the response into a map.\n var r map[string]interface{}\n if err := json.NewDecoder(res.Body).Decode(\u0026amp;r); err != nil {\n log.Printf(\u0026quot;Error parsing the response body: %s\u0026quot;, err)\n } else {\n // Print the response status and indexed document version.\n log.Printf(\u0026quot;[%s] %s; version=%d\u0026quot;, res.Status(), r[\u0026quot;result\u0026quot;], int(r[\u0026quot;_version\u0026quot;].(float64)))\n }\n }\n }(i, title)\n }\n wg.Wait()\n\n log.Println(strings.Repeat(\u0026quot;-\u0026quot;, 37))\n\n // 3. Search for the indexed documents\n //\n // Use the helper methods of the client.\n res, err = es.Search(\n es.Search.WithContext(context.Background()),\n es.Search.WithIndex(\u0026quot;test\u0026quot;),\n es.Search.WithBody(strings.NewReader(`{\u0026quot;query\u0026quot; : { \u0026quot;match\u0026quot; : { \u0026quot;title\u0026quot; : \u0026quot;test\u0026quot; } }}`)),\n es.Search.WithTrackTotalHits(true),\n es.Search.WithPretty(),\n )\n if err != nil {\n log.Fatalf(\u0026quot;ERROR: %s\u0026quot;, err)\n }\n defer res.Body.Close()\n\n if res.IsError() {\n var e map[string]interface{}\n if err := json.NewDecoder(res.Body).Decode(\u0026amp;e); err != nil {\n log.Fatalf(\u0026quot;error parsing the response body: %s\u0026quot;, err)\n } else {\n // Print the response status and error information.\n log.Fatalf(\u0026quot;[%s] %s: %s\u0026quot;,\n res.Status(),\n e[\u0026quot;error\u0026quot;].(map[string]interface{})[\u0026quot;type\u0026quot;],\n e[\u0026quot;error\u0026quot;].(map[string]interface{})[\u0026quot;reason\u0026quot;],\n )\n }\n }\n\n if err := json.NewDecoder(res.Body).Decode(\u0026amp;r); err != nil {\n log.Fatalf(\u0026quot;Error parsing the response body: %s\u0026quot;, err)\n }\n // Print the response status, number of results, and request duration.\n log.Printf(\n \u0026quot;[%s] %d hits; took: %dms\u0026quot;,\n res.Status(),\n int(r[\u0026quot;hits\u0026quot;].(map[string]interface{})[\u0026quot;total\u0026quot;].(map[string]interface{})[\u0026quot;value\u0026quot;].(float64)),\n int(r[\u0026quot;took\u0026quot;].(float64)),\n )\n // Print the ID and document source for each hit.\n for _, hit := range r[\u0026quot;hits\u0026quot;].(map[string]interface{})[\u0026quot;hits\u0026quot;].([]interface{}) {\n log.Printf(\u0026quot; * ID=%s, %s\u0026quot;, hit.(map[string]interface{})[\u0026quot;_id\u0026quot;], hit.(map[string]interface{})[\u0026quot;_source\u0026quot;])\n }\n\n log.Println(strings.Repeat(\u0026quot;=\u0026quot;, 37))\n}\n\n// ~~~~~~~\u0026gt; Elasticsearch 7.0.0-SNAPSHOT\n// [200 OK] updated; version=1\n// [200 OK] updated; version=1\n// -------------------------------------\n// [200 OK] 2 hits; took: 7ms\n// * ID=1, map[title:Test One]\n// * ID=2, map[title:Test Two]\n// =====================================\n
\n
如上述示例所示,esapi
包允许通过两种不同的方式调用Elasticsearch API:通过创建结构(如IndexRequest
),并向其传递上下文和客户端来调用其Do()
方法,或者通过客户端上可用的函数(如WithIndex()
)直接调用其上的Search()
函数。更多信息请参阅包文档。
estransport
包处理与Elasticsearch之间的数据传输。 目前,这个实现只占据很小的空间:它只在已配置的集群端点上进行循环。后续将添加更多功能:重试失败的请求,忽略某些状态代码,自动发现群集中的节点等等。
_examples
文件夹包含许多全面的示例,可帮助你上手使用客户端,包括客户端的配置和自定义,模拟单元测试的传输,将客户端嵌入自定义类型,构建查询,执行请求和解析回应。
遵循Apache License 2.0版本。
\n参考链接:
\nhttps://github.com/elastic/go-elasticsearch#go-elasticsearch
\n