当前位置: 首页 > 工具软件 > Go NES > 使用案例 >

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

侯博易
2023-12-01

说明

\n

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

\n
  • \n
  • 这个项目的工作还在进行中,并非所有计划的功能和Elasticsearch官方客户端中的标准(故障重试,节点自动发现等)都实现了。\n
  • API稳定性无法保证。 尽管公共API的设计非常谨慎,但它们可以根据进一步的探索和用户反馈以不兼容的方式进行更改。\n
  • 客户端的目标是Elasticsearch 7.x版本。后续将添加对6.x和5.x版本API的支持。\n
\n

安装

\n

go get安装这个包:

\n
go get -u github.com/elastic/go-elasticsearch\n
\n

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

\n
require github.com/elastic/go-elasticsearch v0.0.0\n
\n

或者克隆这个仓库:

\n
git clone https://github.com/elastic/go-elasticsearch.git \u0026amp;\u0026amp; cd go-elasticsearch\n
\n

一个完整的示例:

\n
mkdir 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

用法

\n

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

\n

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

\n
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环境变量时,它将被用作集群端点。

\n

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

\n
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()函数。更多信息请参阅包文档。

\n

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

\n

Examples

\n

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

\n

许可证

\n

遵循Apache License 2.0版本。

\n

参考链接:

\n

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

\n
 类似资料: