成人免费xxxxx在线视频软件_久久精品久久久_亚洲国产精品久久久_天天色天天色_亚洲人成一区_欧美一级欧美三级在线观看

半年時間聚合桶數量指定都忘了

開發
本文通過 demo 示例,從發現聚合桶數量丟失,到排查產生丟失的問題,最后通過 size 參數解決聚合桶數量丟失問題的過程。

一、版本

elasticsearch 8.13

二、背景

最近接到一個需求,將 MySQL 中的數據遷移到 Elasticsearch 中,并且相關的業務接口全部切換為使用 Elasticsearch 實現。

其中有個統計的功能,先根據 group 進行分組,然后對每個組內對象的 type 值進行分組統計。

舉個例子:對學生進行統計,相當于先按照班級分組,在統計每個班級里面男女生的人數。

我一想切換到 Elasticsearch 中,相當于嵌套子聚合,一個聚合查詢就出來結果,半小時搞定這個接口。

三、問題來了

1.初始化數據

創建索引:

PUT zuiyu_index
{
  "settings": {
    "number_of_replicas": 1,
    "number_of_shards": 1
  },
  "mappings": {
    "properties": {
      "group": {
        "type": "text",
        "fields": {
          "keyword": {
            "type": "keyword",
            "ignore_above": 256
          }
        }
      },
      "type": {
        "type": "long"
      }
    }
  }
}

插入測試數據:

POST _bulk
{ "index" : { "_index" : "zuiyu_index", "_id" : "1" } }
{ "group" : "1","type":1 ,"sort":1}
{ "index" : { "_index" : "zuiyu_index", "_id" : "2" } }
{ "group" : "1","type":2 ,"sort":1}
{ "index" : { "_index" : "zuiyu_index", "_id" : "3" } }
{ "group" : "1","type":3 ,"sort":1}
{ "index" : { "_index" : "zuiyu_index", "_id" : "4" } }
{ "group" : "2","type":1 ,"sort":1}
{ "index" : { "_index" : "zuiyu_index", "_id" : "5" } }
{ "group" : "2","type":1 ,"sort":1}
{ "index" : { "_index" : "zuiyu_index", "_id" : "6" } }
{ "group" : "2","type":1 ,"sort":1}
{ "index" : { "_index" : "zuiyu_index", "_id" : "7" } }
{ "group" : "3","type":2 ,"sort":1}
{ "index" : { "_index" : "zuiyu_index", "_id" : "8" } }
{ "group" : "4","type":1 ,"sort":1}
{ "index" : { "_index" : "zuiyu_index", "_id" : "9" } }
{ "group" : "5","type":1 ,"sort":1}
{ "index" : { "_index" : "zuiyu_index", "_id" : "10" } }
{ "group" : "6","type":1 ,"sort":1}
{ "index" : { "_index" : "zuiyu_index", "_id" : "11" } }
{ "group" : "7","type":1 ,"sort":1}
{ "index" : { "_index" : "zuiyu_index", "_id" : "12" } }
{ "group" : "8","type":1 ,"sort":1}
{ "index" : { "_index" : "zuiyu_index", "_id" : "13" } }
{ "group" : "9","type":1 ,"sort":1}
{ "index" : { "_index" : "zuiyu_index", "_id" : "14" } }
{ "group" : "10","type":1 ,"sort":1}
{ "index" : { "_index" : "zuiyu_index", "_id" : "15" } }
{ "group" : "10","type":2 ,"sort":1}
{ "index" : { "_index" : "zuiyu_index", "_id" : "16" } }
{ "group" : "11","type":1 ,"sort":1}
{ "index" : { "_index" : "zuiyu_index", "_id" : "17" } }
{ "group" : "11","type":3 ,"sort":1}

像這種簡單的一條 sql 就出來結果的業務,我一般都是先寫個 sql 語句,然后根據 sql 再寫代碼。所以這里我就先寫了個DSL語句。

2.聚合查詢

GET zuiyu_index/_search
{
  "aggregations": {
    "agg_group": {
      "aggregations": {
        "agg_type": {
          "terms": {
            "field": "type"
          }
        }
      },
      "terms": {
        "field": "group.keyword"
      }
    }
  },
  "query": {
    "bool": {
      "must": [
        {
          "terms": {
            "group.keyword": ["1","2","3","4","5","6","7","8","9","10","11"]
          }
        }
      ]
    }
  },
  "size":0
}

同學們可以看一下上面的語句有問題嗎,如果你能發現問題,那么這篇文章也希望你能看下去,也許會有意想不到的收獲。

提示一下:就像標題所說,可以關心一下聚合桶的數量。

四、發現問題

上述 DSL 語句執行之后,大眼一看 ,結果 OK,是我想要的,那就按這個邏輯直接寫 Java 代碼。上述 DSL 語句中聚合操作對應的 Java 代碼如下:

Aggregation aggType = Aggregation.of(agg -> agg.terms(t -> t.field("type")));
 Aggregation aggGroup = Aggregation.of(agg -> agg.terms(t -> t.field("group"))
                .aggregations("agg_type", aggType));

做接口數據層的遷移,最簡單的就是修改完業務代碼之后直接對比返回結果,保持返回結果的一致,這樣的修改對于前端來說沒有影響。

所以,修改完代碼之后直接拿接口的返回值與修改之前的版本進行比對,驗證業務邏輯是否一致。直接 F12 控制臺,找到該接口的返回值,復制,粘貼到對比工具中,進行對比。

此處使用的對比工具是 Beyond Compare 。

通過對比返回結果發現,聚合桶的數量少了一個。

上面的例子中,我們的預期結果是,最外層 group 的分組最少11個,排除 group 不存在的情況。這里 terms 中條件 group 在索引中都已存在。

然后我就趕緊再去執行了一遍上面 DSL 語句,一個一個的驗證聚合桶,發現返回結果中竟然沒有 group=9 的桶存在。

DSL 返回結果如下:

{
  "took": 2,
  "timed_out": false,
  "_shards": {
    "total": 1,
    "successful": 1,
    "skipped": 0,
    "failed": 0
  },
  "hits": {
    "total": {
      "value": 17,
      "relation": "eq"
    },
    "max_score": null,
    "hits": []
  },
  "aggregations": {
    "agg_group": {
      "doc_count_error_upper_bound": 0,
      "sum_other_doc_count": 1,
      "buckets": [
        {
          "key": "1",
          "doc_count": 3,
          "agg_type": {
            "doc_count_error_upper_bound": 0,
            "sum_other_doc_count": 0,
            "buckets": [
              {
                "key": 1,
                "doc_count": 1
              },
              {
                "key": 2,
                "doc_count": 1
              },
              {
                "key": 3,
                "doc_count": 1
              }
            ]
          }
        },
        {
          "key": "2",
          "doc_count": 3,
          "agg_type": {
            "doc_count_error_upper_bound": 0,
            "sum_other_doc_count": 0,
            "buckets": [
              {
                "key": 1,
                "doc_count": 3
              }
            ]
          }
        },
        {
          "key": "10",
          "doc_count": 2,
          "agg_type": {
            "doc_count_error_upper_bound": 0,
            "sum_other_doc_count": 0,
            "buckets": [
              {
                "key": 1,
                "doc_count": 1
              },
              {
                "key": 2,
                "doc_count": 1
              }
            ]
          }
        },
        {
          "key": "11",
          "doc_count": 2,
          "agg_type": {
            "doc_count_error_upper_bound": 0,
            "sum_other_doc_count": 0,
            "buckets": [
              {
                "key": 1,
                "doc_count": 1
              },
              {
                "key": 3,
                "doc_count": 1
              }
            ]
          }
        },
        {
          "key": "3",
          "doc_count": 1,
          "agg_type": {
            "doc_count_error_upper_bound": 0,
            "sum_other_doc_count": 0,
            "buckets": [
              {
                "key": 2,
                "doc_count": 1
              }
            ]
          }
        },
        {
          "key": "4",
          "doc_count": 1,
          "agg_type": {
            "doc_count_error_upper_bound": 0,
            "sum_other_doc_count": 0,
            "buckets": [
              {
                "key": 1,
                "doc_count": 1
              }
            ]
          }
        },
        {
          "key": "5",
          "doc_count": 1,
          "agg_type": {
            "doc_count_error_upper_bound": 0,
            "sum_other_doc_count": 0,
            "buckets": [
              {
                "key": 1,
                "doc_count": 1
              }
            ]
          }
        },
        {
          "key": "6",
          "doc_count": 1,
          "agg_type": {
            "doc_count_error_upper_bound": 0,
            "sum_other_doc_count": 0,
            "buckets": [
              {
                "key": 1,
                "doc_count": 1
              }
            ]
          }
        },
        {
          "key": "7",
          "doc_count": 1,
          "agg_type": {
            "doc_count_error_upper_bound": 0,
            "sum_other_doc_count": 0,
            "buckets": [
              {
                "key": 1,
                "doc_count": 1
              }
            ]
          }
        },
        {
          "key": "8",
          "doc_count": 1,
          "agg_type": {
            "doc_count_error_upper_bound": 0,
            "sum_other_doc_count": 0,
            "buckets": [
              {
                "key": 1,
                "doc_count": 1
              }
            ]
          }
        }
      ]
    }
  }
}

到了這,其實我還沒想到是什么原因造成的,然后看了好幾遍的聚合語句,都沒有發現問題。一度的自我懷疑,聚合不是這樣用的嗎,嵌套的聚合難道還有花樣?

1.查閱官方文檔

官方文檔肯定是最權威的,所以去官方文檔看看吧,是不是可以給自己點靈感,找到解決方案。

首先去的是如下地址:

https://www.elastic.co/guide/en/elasticsearch/reference/current/search-aggregations.html#run-sub-aggs

官方給的代碼示例好簡單,確實沒毛病,對我沒啥啟發,告辭轉下個網頁。

還是這個網頁,回到頁面頂端,有一個 Bucket 字樣的地方,點進去。

https://www.elastic.co/guide/en/elasticsearch/reference/current/search-aggregations-bucket.html

在這個頁面,發現可以通過 search.max_buckets 設置請求返回聚合桶的總數,然后我腦海中那丟失的記憶回來了。

想起了在 Elasticsearch 聚合時,聚合桶的返回數量是可以指定的,但是怎么指定,參數是什么,我又忘了。

但是大方向肯定是這個了,我就開始找相關的資料,翻閱官網關于聚合的文檔,終于在官方文檔的嵌套聚合中找到了相關的說明。

https://www.elastic.co/guide/en/elasticsearch/reference/current/search-aggregations-bucket-composite-aggregation.html#_size

大體意思就是size參數可以控制返回聚合桶的數量,默認 10。

但是這里也沒有給出示例,我還是不會用啊。

畢竟咱也是有點 ES 基礎的,內心其實已經有了想法,大概知道怎么用了,只是還得需要確認下。

最后想起來之前寫過關于聚合的文章,抱著試試看的態度,在回顧一下吧。

2.聚合在Elasticsearch中的使用及示例驗證

發文日期,2023年8月2日,真是老了,才半年多的時間都忘了,好了回到主題。

在這篇文檔中,發現了 size 參數的使用,在這里終于確認,聚合桶數量需要指定,并且根據自己的查詢條件進行設置,或直接設置一個最大值兼容自己所有的聚合請求。

所以修改之后的 DSL 語句如下:

GET zuiyu_index/_search
{
  "aggregations": {
    "agg_group": {
      "aggregations": {
        "agg_type": {
          "terms": {
            "field": "type"
          }
        }
      },
      "terms": {
        "field": "group.keyword",
        "size": 11
      }
    }
  },
  "query": {
    "bool": {
      "must": [
        {
          "terms": {
            "group.keyword": ["1","2","3","4","5","6","7","8","9","10","11"]
          }
        }
      ]
    }
  },
  "size":0
}

相對應的 Java 代碼也修改:

Aggregation aggType = Aggregation.of(agg -> agg.terms(t -> t.field("type")));
 Aggregation aggGroup = Aggregation.of(agg -> agg.terms(t -> t.field("group").size(groupList.size())
                .aggregations("agg_type", aggType));

groupList.size() 為 terms 查詢條件值的數量。

五、search.max_buckets

可以通過 _cluster 的 API 設置此參數。

PUT _cluster/settings
{
  "transient": {
    "search.max_buckets":100
  }
}

此處使用的是 transient ,還可以使用 persistent,他倆的區別就是transient 的配置會在集群重啟之后失效,persistent會持久化保存。

其中這個參數在之前的索引分片分配策略一文中講過了,還沒看過的可以跳過去看一下,鏈接我放下面。

Elasticsearch Index Shard Allocation 索引分片分配策略

六、總結

本文通過 demo 示例,從發現聚合桶數量丟失,到排查產生丟失的問題,最后通過 size 參數解決聚合桶數量丟失問題的過程。

意外收獲的是一次請求返回聚合桶數量的總數也是可以通過 search.max_buckets設置的。

日常的積累固然重要,熟悉官方文檔中相關 API 的位置也是必不可少的。

責任編輯:趙寧寧 來源: 醉魚Java
相關推薦

2017-11-02 10:15:12

時間 1元

2020-11-18 17:37:05

C語言Java程序員

2013-05-21 10:19:22

2015-09-24 10:29:50

PC市場Windows 10

2020-09-02 09:08:28

5G運營商5G基站

2020-05-22 13:27:49

5G網絡張云勇運營商

2025-04-17 08:09:22

開源項目Member

2021-12-16 12:27:15

Log4j漏洞網絡安全

2015-01-06 09:59:03

2012-06-28 09:32:15

Windows RTMetro

2012-12-28 16:23:50

2023-11-26 18:13:07

iOS 18蘋果

2013-09-29 09:43:40

戴爾CEO私有化

2015-08-12 13:20:48

2g

2012-10-08 10:14:17

Instagram

2016-08-08 17:37:23

大數據搜索

2024-07-31 16:21:08

2011-06-29 09:58:01

IBMCell刀片服務器QS22

2013-09-04 11:31:45

2023-03-09 08:02:14

范圍數量元素
點贊
收藏

51CTO技術棧公眾號

主站蜘蛛池模板: 欧美日韩一区二区三区在线观看 | 午夜在线观看免费 | 成人在线电影在线观看 | 国产精品视频久久 | 黄色一级大片视频 | 亚洲综合区| 青青草精品视频 | 一区二区三区在线播放 | 97国产精品视频人人做人人爱 | 毛片入口| 粉嫩一区二区三区四区公司1 | 日本 欧美 国产 | 精品91av| 免费观看黄色一级片 | 欧美极品在线 | 国产亚洲精品精品国产亚洲综合 | 国产人成精品一区二区三 | 欧美视频第二页 | 成人av网站在线观看 | 97超碰人人草 | 久草新在线 | 波多野结衣中文字幕一区二区三区 | 国产一区二区三区久久久久久久久 | 伊人久久国产 | 色黄爽| 狠狠操电影 | 国产日韩欧美一区二区 | 中文字幕av一区 | 波多野结衣先锋影音 | 成人一区二区三区 | 一区二区精品 | 欧美日本在线观看 | 97视频精品| 久久久久一区二区三区 | 呦呦在线视频 | 国产成人久久精品一区二区三区 | 国产精品久久久久久久久久免费看 | 日韩一区二区三区视频 | 毛片一区二区 | 91一区二区在线观看 | 成人精品一区亚洲午夜久久久 |