当前位置:   article > 正文

使用 go-elasticsearch v8 基本请求_go elasticsearch 8

go elasticsearch 8

使用 go-elasticsearch 请求示例

你可以通过参考Go 官方文档找到简单的示例,所以我认为先看看这个是个好主意。

连接客户端有两种方式,如下图。
至于两者的特点,TypedClient有类型,更容易编写,但文档较少。另外,批量索引不支持TypedClient。由于普通客户端都是基于json的,所以我觉得从文档转换到代码还是比较容易的。

我的建议基本上是使用 TypedClient!
虽然文档很稀疏,但它是基于规律性的类型化的,所以你越习惯它(特别是当涉及到有很多变化的东西时,比如查询),从 json 转换为类型化代码就越容易。

  1. func main() {
  2. // client
  3. es, err := elasticsearch.NewClient(elasticsearch.Config{
  4. Addresses: []string{"http://localhost:9200"},
  5. })
  6. if err != nil {
  7. log.Fatalf("Error creating the client: %s", err)
  8. }
  9. // typed client
  10. es, err := elasticsearch.NewTypedClient(elasticsearch.Config{
  11. Addresses: []string{"http://localhost:9200"},
  12. })
  13. if err != nil {
  14. log.Fatalf("Error creating the client: %s", err)
  15. }
  16. }

Index Create/Delete

关于索引创建,Go官方文档中有一个示例,所以我简单介绍一下。

  1. func main() {
  2. es, err := elasticsearch.NewTypedClient(elasticsearch.Config{
  3. Addresses: []string{"http://localhost:9200"},
  4. })
  5. if err != nil {
  6. log.Fatalf("Error creating the client: %s", err)
  7. }
  8. ignoreAbove := 256
  9. keywordProperty := types.NewKeywordProperty()
  10. keywordProperty.IgnoreAbove = &ignoreAbove
  11. dateProperty := types.NewDateProperty()
  12. format := "yyyy/MM/dd||yyyy/MM||MM/dd||yyyy||MM||dd"
  13. dateProperty.Format = &format
  14. // index作成
  15. _, err = es.Indices.Create("sample_index").Request(&create.Request{
  16. Settings: &types.IndexSettings{
  17. IndexSettings: map[string]json.RawMessage{
  18. // 設定項目
  19. // bulk index里面的数据更新感觉。如果不需要频繁更新,设置得更长会提高性能。
  20. "refresh_interval": json.RawMessage(`"30s"`),
  21. // 可取得的最大件数的上限
  22. "max_result_window": json.RawMessage(`"1000000"`),
  23. },
  24. },
  25. Mappings: &types.TypeMapping{
  26. Properties: map[string]types.Property{
  27. // 映射的定义
  28. "name": keywordProperty,
  29. "age": types.NewIntegerNumberProperty(),
  30. "is_checked": types.NewBooleanProperty(),
  31. "created_at": dateProperty,
  32. },
  33. },
  34. }).Do(context.TODO())
  35. if err != nil {
  36. log.Fatalf("Error creating the client: %s", err)
  37. }
  38. // index削除
  39. _, err = es.Indices.Delete("sample_index").Do(context.TODO())
  40. if err != nil {
  41. log.Fatalf("Error deleting the client: %s", err)
  42. }
  43. }

Bulk Index

批量索引代码基于go-elasticsearch 示例。

  1. var jsonitier = jsoniter.ConfigCompatibleWithStandardLibrary
  2. type SampleIndexData struct {
  3. ID int64 `json:"id"`
  4. Name string `json:"name"`
  5. Age int `json:"age"`
  6. IsChecked bool `json:"is_checked"`
  7. CreatedAt string `json:"created_at"`
  8. }
  9. func main() {
  10. es, err := elasticsearch.NewClient(elasticsearch.Config{
  11. Addresses: []string{"http://localhost:9200"},
  12. })
  13. if err != nil {
  14. log.Fatalf("Error creating the client: %s", err)
  15. }
  16. esRef, err := elasticsearch.NewTypedClient(elasticsearch.Config{
  17. Addresses: []string{"http://localhost:9200"},
  18. })
  19. if err != nil {
  20. log.Fatalf("Error creating the client: %s", err)
  21. }
  22. datas := []*SampleIndexData{}
  23. for i := 1; i <= 100; i++ {
  24. datas = append(datas, &SampleIndexData{
  25. ID: int64(i),
  26. Name: fmt.Sprintf("name_%d", i),
  27. Age: 20,
  28. IsChecked: true,
  29. CreatedAt: time.Date(2021, 1, 15, 17, 28, 55, 0, jst).Format("2006/01/02"),
  30. })
  31. }
  32. bi, err := esutil.NewBulkIndexer(esutil.BulkIndexerConfig{
  33. Index: "sample_index", // The default index name
  34. Client: es, // The Elasticsearch client
  35. NumWorkers: 1, // The number of worker goroutines
  36. })
  37. if err != nil {
  38. log.Fatalf("Error creating the indexer: %s", err)
  39. }
  40. for _, a := range datas {
  41. data, err := jsonitier.Marshal(a)
  42. if err != nil {
  43. log.Fatalf("Cannot encode article %d: %s", a.ID, err)
  44. }
  45. err = bi.Add(
  46. context.Background(),
  47. esutil.BulkIndexerItem{
  48. // Delete时,action为“delete”,body为nil。
  49. Action: "index",
  50. DocumentID: strconv.Itoa(int(a.ID)),
  51. Body: bytes.NewReader(data),
  52. OnSuccess: func(ctx context.Context, item esutil.BulkIndexerItem, res esutil.BulkIndexerResponseItem) {
  53. fmt.Println("success")
  54. },
  55. OnFailure: func(ctx context.Context, item esutil.BulkIndexerItem, res esutil.BulkIndexerResponseItem, err error) {
  56. fmt.Println("failure")
  57. },
  58. },
  59. )
  60. if err != nil {
  61. log.Fatalf("Unexpected error: %s", err)
  62. }
  63. }
  64. if err := bi.Close(context.Background()); err != nil {
  65. log.Fatalf("Unexpected error: %s", err)
  66. }
  67. // 取决于refresh_interval的值,但是如果感觉很长,在所有的index结束后刷新,数据会立即反映出来,所以很好
  68. _, err = esRef.Indices.Refresh().Index("sample_index").Do(context.Background())
  69. if err != nil {
  70. log.Fatalf("Error getting response: %s", err)
  71. }
  72. }

Query

基本查询如下所示:

Go 的官方文档仅包含搜索 API 的简单示例。您基本上必须自己组装上述详细信息。就我而言,我正在检查QueryDSL页面上的查询并在中复制我需要的内容。

  1. var jst = time.FixedZone("Asia/Tokyo", 9*60*60)
  2. var formatTime = "2006-01-02T15:04:05.999999-07:00"
  3. func main() {
  4. es, err := elasticsearch.NewTypedClient(elasticsearch.Config{
  5. Addresses: []string{"http://localhost:9200"},
  6. })
  7. if err != nil {
  8. log.Fatalf("Error creating the client: %s", err)
  9. }
  10. ageLte := 40.0
  11. ageLteC := (*types.Float64)(&ageLte)
  12. ageGte := 13.0
  13. ageGteC := (*types.Float64)(&ageGte)
  14. pageStart := 0
  15. size := 50
  16. req := &search.Request{
  17. // 查询
  18. Query: &types.Query{
  19. Bool: &types.BoolQuery{
  20. // 过滤器(过滤器)
  21. Filter: []types.Query{
  22. // 范围过滤器(过滤器)
  23. {
  24. Range: map[string]types.RangeQuery{
  25. "age": types.NumberRangeQuery{
  26. Gte: ageGteC,
  27. Lte: ageLteC,
  28. },
  29. },
  30. },
  31. // 术语过滤器(过滤器)
  32. {
  33. Term: map[string]types.TermQuery{
  34. "is_checked": {Value: true},
  35. },
  36. },
  37. },
  38. },
  39. },
  40. // 页面的起点
  41. From: &pageStart,
  42. // 返回的数量
  43. Size: &size,
  44. // 排序指定
  45. Sort: []types.SortCombinations{
  46. types.SortOptions{SortOptions: map[string]types.FieldSort{
  47. "created_at": {Order: &sortorder.Desc},
  48. }},
  49. },
  50. }
  51. res, err := es.Search().
  52. Index("sample_index").
  53. Request(req).
  54. Do(context.TODO())
  55. if err != nil {
  56. log.Fatalf("Error query: %s", err)
  57. }
  58. // total
  59. fmt.Println(res.Hits.Total)
  60. ds := []*SampleIndexData{}
  61. for _, hit := range res.Hits.Hits {
  62. var d *SampleIndexData
  63. if err := json.Unmarshal(hit.Source_, &d); err != nil {
  64. log.Fatalf("Error decoding: %s", err)
  65. }
  66. ds = append(ds, d)
  67. }
  68. // 拿出数据.
  69. fmt.Println(ds)
  70. }

此外,您还可以使用 kibana 中的 devtools 轻松检查详细错误,以查看查询是否正确。为了调整查询以使其正确,最好使用一个围绕此问题的工具(在代码中,它也包含在 err 中,所以也在那里检查它。我可以)。

综上所述

我已经简要描述了基本的索引创建/删除、使用 Bulk API 的批量处理以及如何在 go-elasticsearch 中使用 SearchAPI 编写搜索查询。

就我个人而言,我发现很容易迷失在 Elasticsearch 的文档中,当我尝试做一些详细的事情时,我最终会输入大量代码并进行反复试验,因此需要花费大量时间来理解整体概念并编写代码。

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/从前慢现在也慢/article/detail/166762
推荐阅读
相关标签
  

闽ICP备14008679号