国产 无码 综合区,色欲AV无码国产永久播放,无码天堂亚洲国产AV,国产日韩欧美女同一区二区

使用Elasticsearch進(jìn)行分組聚合統(tǒng)計

這篇具有很好參考價值的文章主要介紹了使用Elasticsearch進(jìn)行分組聚合統(tǒng)計。希望對大家有所幫助。如果存在錯誤或未考慮完全的地方,請大家不吝賜教,您也可以點(diǎn)擊"舉報違法"按鈕提交疑問。

要使用Elasticsearch進(jìn)行分組聚合統(tǒng)計,可以使用聚合(aggregation)功能。聚合操作允許您根據(jù)指定的條件對文檔進(jìn)行分組,并計算每個分組的聚合結(jié)果。

針對普通類型的字段,DSL構(gòu)建語法:

{
  "aggs": {
    "agg_name": {
      "agg_type": {
        "agg_parameters"
      }
    },
    "agg_name2": {
      "agg_type": {
        "agg_parameters"
      }
    },
    ...
  }
}

aggs:?aggregations關(guān)鍵字的別名,代表著分組

agg_name: 這個是自定義的名字,可以針對你自己的字段命名一個,最好加上_agg后綴

agg_type: 聚合類型

agg_parameters:聚合參數(shù)

聚合類型(agg_type)

Elasticsearch中支持多種聚合類型(agg_type)用于不同的聚合操作。以下是一些常用的聚合類型及其功能:

  1. Terms(詞條聚合):按照字段值進(jìn)行分組,統(tǒng)計每個分組的文檔數(shù)量。
  2. Sum(求和聚合):計算指定字段的總和。
  3. Avg(平均值聚合):計算指定字段的平均值。
  4. Min(最小值聚合):找出指定字段的最小值。
  5. Max(最大值聚合):找出指定字段的最大值。
  6. Stats(統(tǒng)計聚合):計算指定字段的統(tǒng)計信息,包括最小值、最大值、總和、平均值和文檔數(shù)量。
  7. Extended Stats(擴(kuò)展統(tǒng)計聚合):計算指定字段的擴(kuò)展統(tǒng)計信息,包括最小值、最大值、總和、平均值、標(biāo)準(zhǔn)差和文檔數(shù)量。
  8. Cardinality(基數(shù)聚合):計算指定字段的唯一值數(shù)量。
  9. Date Histogram(日期直方圖聚合):按照時間間隔對日期字段進(jìn)行分組。
  10. Range(范圍聚合):將文檔按照指定范圍進(jìn)行分組,例如按照價格范圍、年齡范圍等。
  11. Nested(嵌套聚合):在嵌套字段上執(zhí)行子聚合操作。

除了上述示例外,Elasticsearch還提供了更多聚合類型,如Geo Distance(地理距離聚合)、Date Range(日期范圍聚合)、Filter(過濾聚合)等。

聚合參數(shù)(agg_parameters)

在Elasticsearch中,聚合(aggregation)可以使用不同的參數(shù)來控制其行為和結(jié)果。以下是一些常用的聚合參數(shù):

1. field(字段):指定要聚合的字段。
2. size(大?。合拗品祷氐木酆贤暗臄?shù)量。
3. script(腳本):使用腳本定義聚合邏輯。
4. min_doc_count(最小文檔數(shù)量):指定聚合桶中文檔的最小數(shù)量要求。
5. order(排序):按照指定字段對聚合桶進(jìn)行排序。
6. include/exclude(包含/排除):根據(jù)指定的條件包含或排除聚合桶。
7. format(格式):對聚合結(jié)果進(jìn)行格式化。
8. precision_threshold(精度閾值):用于基數(shù)聚合的精度控制。
9. interval(間隔):用于日期直方圖聚合的時間間隔設(shè)置。
10. range(范圍):用于范圍聚合的范圍定義。

具體可用的參數(shù)取決于聚合類型和使用的Elasticsearch版本。

DSL查詢實(shí)踐

準(zhǔn)備工具:?Kibana或者Elasticvue

在這里,我使用Elasticvue

網(wǎng)址:Elasticvue - Elasticsearch gui for the browser

這個工具我是裝在火狐上的,連接上后能看到節(jié)點(diǎn)信息、集群健康、索引信息等等,也支持REST查詢,類似在Kibana使用Devtools差不多。

elasticsearch聚合統(tǒng)計,Elasticsearch,elasticsearch,大數(shù)據(jù),搜索引擎

單個分組DSL查詢, 求分組后的平均值

{
  "size": 0,
  "aggs": {
    "id_agg": {
      "terms": {
        "field": "id", 
        "size": 3 #在有的情況下,如果你的文檔數(shù)量太多,會導(dǎo)致查詢超時、返回數(shù)據(jù)過多的問題
      },
      "aggs": {
        "sub_id_agg": { 
          "terms": { #匹配搜索
            "field": "id"
          }
        }
      }
    }
  }
}

?

?這張圖上面有幾個關(guān)鍵信息

`/orderv4/order/_search` 是一個 Elasticsearch 的 REST API 端點(diǎn),用于執(zhí)行針對名為 `order` 的索引的搜索操作。

  1. /orderv4/order: 表示索引的名稱是 `orderv4`,類型(Type)的名稱是 `order`。
  2. 在較新的 Elasticsearch 版本中,類型的概念已經(jīng)逐漸被棄用,因此索引名稱后面的 `/order` 可以省略。
  3. _search: 表示執(zhí)行搜索操作。

左側(cè)是DSL請求體,右邊是返回結(jié)果

took: 執(zhí)行搜索的時間,單位是毫秒

timed_out:搜索是否超時

_shards:分片執(zhí)行情況,這里的total代表參與搜索的總分片數(shù)

hits:和搜索文檔匹配的文檔信息,total代表和搜索條件匹配的總文檔數(shù)

aggregations:里面是聚合結(jié)果,id_agg是剛才在dsl查詢的時候設(shè)置的聚合名稱,sum_other_doc_count代表除了bucket里面的文檔數(shù)量,還有多少條沒有展示。buckets里面的key就是文檔里面的id的值是多少,doc_count 表示文檔數(shù)量,換句話來說就是,id = 0 的數(shù)量為 1

使用Java構(gòu)建分組查詢

SearchSourceBuilder searchSourceBuilder = new SearchSourceBuilder();

// 添加聚合操作
TermsAggregationBuilder aggregationBuilder = AggregationBuilders.terms("id_agg").field("id");
aggregationBuilder.subAggregation(AggregationBuilders.terms("sub_id_agg").field("id"));

searchSourceBuilder.aggregation(aggregationBuilder);

基于nested嵌套類型分組查詢

nested(嵌套)是一種特殊的數(shù)據(jù)類型和查詢方式,用于處理嵌套文檔結(jié)構(gòu)。它允許在文檔中嵌套其他文檔,并以一種有層次結(jié)構(gòu)的方式進(jìn)行索引和查詢。

在使用nested查詢的時候,先要對你的索引設(shè)置Mapping配置。把字段類型設(shè)置為nested。

一種是在建索引的時候,就配好Mapping,另外一種方式是直接對索引文檔更新。

POST youer_index/_mapping/your_type
{
    "properties":{
        "item_list":{ # 在Java的ESDO模型里,就代表了一個List<Item>, Item是你自己定義的業(yè)務(wù)對象
            "type":"nested", #給item_list設(shè)置嵌套類型
            "properties":{
                "id":{
                    "type":"long"
                },
                "name":{
                    "type":"string"
                },
                "price":{
                    "type":"long"
                }
            }
        }
    }
}

nested字段DSL查詢案例

{
    "aggregations":{
        "item_list_agg":{
            "nested":{
                "path":"item_list" # 字段路徑必須,不然查不出結(jié)果
            },
            "aggs":{
                "sub_item_list_agg":{
                    "terms":{
                        "field":"item_list.id"
                    }
                }
            }
        }
    }
}

使用Java構(gòu)建nested分組查詢

SearchSourceBuilder searchSourceBuilder = new SearchSourceBuilder();
// 添加聚合操作
AggregationBuilder nested = AggregationBuilders.nested("id_nested_agg", "item_list");
        
// 構(gòu)建一個terms
TermsAggregationBuilder terms = AggregationBuilders.terms("id_nested_sub_agg").field("id");
        
// 將terms加到nested中
nested.subAggregation(terms);
        
// 添加到最終的查詢中
searchSourceBuilder.aggregation(nested);

更多的案例,如果有興趣的朋友可以自己摸索。下面我就分享一個實(shí)戰(zhàn)中,如何用Java針對普通字段類型和nested字段類型構(gòu)建查詢語句,同時支持返回多個字段值。

import com.github.houbb.heaven.util.lang.StringUtil;
import org.apache.commons.collections.CollectionUtils;
import org.elasticsearch.search.aggregations.AggregationBuilder;
import org.elasticsearch.search.aggregations.AggregationBuilders;

import java.util.ArrayList;
import java.util.List;
import java.util.stream.Collectors;

/**
 * @author : kenny
 * @since : 2023/5/18
 **/
public class AggregationBuilderExample {
    /**
     * 構(gòu)造一個單桶分組查詢,支持普通字段類型和nested字段類型
     * @param aggregationFields
     * @return
     */
    public static AggregationBuilder buildSingeBucketAggregationBuilder(List<String> aggregationFields) {
        if (CollectionUtils.isEmpty(aggregationFields)) {
            throw new RuntimeException("Aggregate search requires aggregate fields!");
        }

        aggregationFields = aggregationFields.stream().filter(StringUtil::isNotEmpty).collect(Collectors.toList());
        String aggregationField = aggregationFields.get(0);
        int dotIndex = aggregationField.indexOf(".");
        AggregationBuilder aggregationBuilder;
        if (dotIndex != -1) {
            String path = aggregationField.substring(0, dotIndex);
            aggregationBuilder = AggregationBuilders.nested(aggregationField + "nested_agg", path);
            AggregationBuilder nestedTerms = AggregationBuilders.terms(aggregationField).field(aggregationField).size(1000);
            aggregationBuilder = aggregationBuilder.subAggregation(nestedTerms);
        }else {
            aggregationBuilder = AggregationBuilders.terms(aggregationField + "_agg").field(aggregationField).size(1000);
        }

        return aggregationBuilder;
    }


    /**
     * 構(gòu)造一個多桶分組查詢,支持普通字段類型和nested字段類型
     * @param aggregationFields
     * @return
     */
    public static List<AggregationBuilder> buildMultiplexBucketAggregationBuilder(List<String> aggregationFields){
        if (CollectionUtils.isEmpty(aggregationFields)) {
            throw new RuntimeException("Aggregate search requires aggregate fields!");
        }

        aggregationFields = aggregationFields.stream().filter(StringUtil::isNotEmpty).collect(Collectors.toList());
        List<AggregationBuilder> aggregations = new ArrayList<>();
        for (String field : aggregationFields){
            int dotIndex = field.indexOf(".");
            AggregationBuilder aggregationBuilder;
            if (dotIndex != -1) {
                String path = field.substring(0, dotIndex);
                aggregationBuilder = AggregationBuilders.nested(field + "_nested_agg", path);
                AggregationBuilder nestedTerms = AggregationBuilders.terms(field).field(field).size(1000);
                aggregationBuilder = aggregationBuilder.subAggregation(nestedTerms);
            }else {
                aggregationBuilder = AggregationBuilders.terms(field).field(field).size(1000);
            }

            aggregations.add(aggregationBuilder);
        }

        return aggregations;
    }
}

針對于結(jié)果的解析我們同樣也構(gòu)造一個解析方法文章來源地址http://www.zghlxwxcb.cn/news/detail-553373.html


import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;

import java.util.ArrayList;
import java.util.Collections;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * @author : kenny
 * @since : 2023/5/18
 **/
public class AggregationResultParserExample {

    /**
     * 針對單桶聚合統(tǒng)計
     * @param json ES執(zhí)行搜索之后返回的MetricAggregation信息
     * @return
     */
    public static Map<String, Integer> parseSingleBucketAggregations(String json) {
        JSONObject jsonObject = JSONObject.parseObject(json);
        if (jsonObject == null){
            return null;
        }

        Map<String, Integer> resultMap = new HashMap<>();
        try {
            internal_ParseSingBucketAggregations(jsonObject, resultMap);
        }catch (Exception ex){
            // 處理你自己的異常
        }
        return resultMap;
    }


    private static void internal_ParseSingBucketAggregations(JSONObject jsonObject, Map<String, Integer> map) {
        for (Map.Entry<String, Object> entry : jsonObject.entrySet()) {
            String key = entry.getKey();
            Object value = entry.getValue();

            if (value instanceof JSONObject) {
                JSONObject childObject = (JSONObject) value;
                if (childObject.containsKey("key") && childObject.containsKey("doc_count")) {
                    String childKey = childObject.getJSONObject("key").getString("value");
                    int docCount = childObject.getJSONObject("doc_count").getIntValue("value");
                    map.put(childKey, docCount);
                }
                internal_ParseSingBucketAggregations(childObject, map);
            } else if (value instanceof JSONArray) {
                JSONArray childArray = (JSONArray) value;
                for (Object element : childArray) {
                    if (element instanceof JSONObject) {
                        JSONObject childObject = (JSONObject) element;
                        internal_ParseSingBucketAggregations(childObject, map);
                    }
                }
            }
        }
    }

    /**
     * 解析多桶分組統(tǒng)計
     * @param json ES執(zhí)行搜索之后返回的MetricAggregation信息
     * @return
     */
    public static Map<String, List<Map<String, Object>>> parseMultiplexBucketAggregations(String json) {
        JSONObject jsonRoot = JSONObject.parseObject(json);
        if (jsonRoot == null){
            return Collections.emptyMap();
        }

        Map<String, List<Map<String, Object>>> resultMap = new HashMap<>();
        try {
            internal_ParseMultiplexBucketAggregations(jsonRoot, "", resultMap);
        }catch (Exception ex){
            // 處理你自己的異常
        }

        return resultMap;
    }

    private static void internal_ParseMultiplexBucketAggregations(JSONObject jsonObject, String prefix, Map<String, List<Map<String, Object>>> resultMap) {
        for (Map.Entry<String, Object> entry : jsonObject.entrySet()) {
            String key = entry.getKey();
            Object value = entry.getValue();

            if (value instanceof JSONObject) {
                JSONObject childObject = (JSONObject) value;
                if (childObject.containsKey("buckets")) {
                    List<Map<String, Object>> bucketList = new ArrayList<>();
                    JSONArray buckets = childObject.getJSONObject("buckets").getJSONArray("elements");
                    for (int i = 0; i < buckets.size(); i++) {
                        JSONObject bucket = buckets.getJSONObject(i);
                        Map<String, Object> bucketMap = new HashMap<>();
                        JSONObject bucketMembers = bucket.getJSONObject("members");
                        for (Map.Entry<String, Object> bucketEntry : bucketMembers.entrySet()) {
                            String bucketKey = bucketEntry.getKey();
                            Object bucketValue = bucketEntry.getValue();
                            if (bucketValue instanceof JSONObject) {
                                JSONObject valueObject = (JSONObject) bucketValue;
                                if (valueObject.containsKey("value")) {
                                    bucketMap.put(bucketKey, valueObject.get("value"));
                                }
                            }
                        }
                        bucketList.add(bucketMap);
                    }

                    resultMap.put(prefix + key, bucketList);
                } else {
                    internal_ParseMultiplexBucketAggregations(childObject, prefix + key + "_", resultMap);
                }
            }
        }
    }
}

到了這里,關(guān)于使用Elasticsearch進(jìn)行分組聚合統(tǒng)計的文章就介紹完了。如果您還想了解更多內(nèi)容,請在右上角搜索TOY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章,希望大家以后多多支持TOY模板網(wǎng)!

本文來自互聯(lián)網(wǎng)用戶投稿,該文觀點(diǎn)僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務(wù),不擁有所有權(quán),不承擔(dān)相關(guān)法律責(zé)任。如若轉(zhuǎn)載,請注明出處: 如若內(nèi)容造成侵權(quán)/違法違規(guī)/事實(shí)不符,請點(diǎn)擊違法舉報進(jìn)行投訴反饋,一經(jīng)查實(shí),立即刪除!

領(lǐng)支付寶紅包贊助服務(wù)器費(fèi)用

相關(guān)文章

  • 五、淺析[ElasticSearch]底層原理與分組聚合查詢

    五、淺析[ElasticSearch]底層原理與分組聚合查詢

    集群節(jié)點(diǎn)介紹 es配置文件夾中 客戶端節(jié)點(diǎn) 當(dāng)主節(jié)點(diǎn)和數(shù)據(jù)節(jié)點(diǎn)配置都設(shè)置為false的時候,該節(jié)點(diǎn)只能處理路由請求,處理搜索,分發(fā)索引操作等,從本質(zhì)上來說該客戶節(jié)點(diǎn)表現(xiàn)為智能負(fù)載平衡器。獨(dú)立的客戶端節(jié)點(diǎn)在一個比較大的集群中是非常有用的,他協(xié)調(diào)主節(jié)點(diǎn)和數(shù)據(jù)節(jié)

    2024年02月16日
    瀏覽(18)
  • ElasticSearch分組統(tǒng)計查詢

    maven依賴: 構(gòu)建配置類: 根據(jù)兩個字段進(jìn)行統(tǒng)計: 實(shí)體定義: 創(chuàng)建索引文件:

    2024年02月02日
    瀏覽(22)
  • ElasticSearch 聚合統(tǒng)計

    ElasticSearch 聚合統(tǒng)計

    度量聚合:求字段的平均值,最小值,最大值,總和等 桶聚合:將文檔分成不同的桶,桶的劃分可以根據(jù)字段的值,范圍,日期間隔 管道聚合:在桶聚合的結(jié)果上執(zhí)行進(jìn)一步計算 進(jìn)行聚合的語法如下 聚合也可以進(jìn)行嵌套 平均值聚合 在 ElasticSearch 中進(jìn)行聚合統(tǒng)計時,默認(rèn)情

    2024年02月04日
    瀏覽(16)
  • ElasticSearch 分組統(tǒng)計,每組取最新數(shù)據(jù)

    ElasticSearch按任務(wù)id分組統(tǒng)計 查詢方法: 任務(wù)ID一個,網(wǎng)站ID若干 求: 按網(wǎng)站ID分組,crawTotal最大,且時間為最新的一條數(shù)據(jù)。

    2024年02月10日
    瀏覽(21)
  • Elasticsearch 查詢和聚合查詢:基本語法和統(tǒng)計數(shù)量

    摘要:Elasticsearch是一個強(qiáng)大的分布式搜索和分析引擎,提供了豐富的查詢和聚合功能。本文將介紹Elasticsearch的基本查詢語法,包括預(yù)發(fā)查詢和聚合查詢,以及如何使用聚合功能統(tǒng)計數(shù)量。 Elasticsearch是一種開源的分布式搜索和分析引擎,廣泛應(yīng)用于各種場景,包括日志分析、

    2024年02月11日
    瀏覽(29)
  • Python-ElasticSearch客戶端的封裝(聚合查詢、統(tǒng)計查詢、全量數(shù)據(jù))

    Python-ElasticSearch客戶端的封裝(聚合查詢、統(tǒng)計查詢、全量數(shù)據(jù))

    官方提供了兩個客戶端elasticsearch、elasticsearch-dsl 第二個是對第一個的封裝,類似ORM操作數(shù)據(jù)庫,可以.filter、.groupby,個人感覺很雞肋,star數(shù)也不多。平時使用的時候一般會在kibana上測試,然后直接把query拷貝過來獲取更多數(shù)據(jù),所以這里做下第一個的封裝。 封裝后依然暴露

    2024年02月14日
    瀏覽(54)
  • 4.4 使用分組聚合進(jìn)行組內(nèi)計算

    4.4 使用分組聚合進(jìn)行組內(nèi)計算

    該方法提供的是分組聚合步驟中的拆分功能,能根據(jù)索引或字段對數(shù)據(jù)進(jìn)行分組 DataFrame.groupby(by=None, axis=0, level=None, as_index=True, sort=True, group_keys=True, squeeze=False, **kwargs) by參數(shù)的特別說明 如果傳入的是一個函數(shù)則對索引進(jìn)行計算并分組。 如果傳入的是一個字典或者Series則字典

    2023年04月23日
    瀏覽(19)
  • 使用 Java 流進(jìn)行分組和聚合,高效處理大量數(shù)據(jù)不再是夢!

    了解使用 Java Streams 解決問題的直接途徑,Java Streams 是一個允許我們快速有效地處理大量數(shù)據(jù)的框架。 當(dāng)我們對列表中的元素進(jìn)行分組時,我們可以隨后聚合分組元素的字段以執(zhí)行有意義的操作,幫助我們分析數(shù)據(jù)。一些示例是加法、平均值或最大值/最小值。這些單個字段

    2024年02月07日
    瀏覽(17)
  • Elasticsearch(三)聚合基本使用

    基礎(chǔ)概念 bucket 數(shù)據(jù)分組,一些數(shù)據(jù)按照某個字段進(jìn)行bucket劃分,這個字段值相同的數(shù)據(jù)放到一個bucket中。可以理解成Java中的MapString, List結(jié)構(gòu),類似于Mysql中的group by后的查詢結(jié)果。 metric: 對一個數(shù)據(jù)分組執(zhí)行的統(tǒng)計,比如計算最大值,最小值,平均值等 類似于Mysql中的max

    2024年02月09日
    瀏覽(20)
  • Elasticsearch使用篇 - 管道聚合

    基于前一次聚合的結(jié)果,進(jìn)行二次聚合統(tǒng)計。 從結(jié)構(gòu)上可以分為兄弟級(Sibling)管道聚合和父級(Parent)管道聚合兩種方式。 兄弟級管道聚合:在同一聚合級別上可以產(chǎn)生新的聚合。 父級管道聚合:由父聚合提供輸出,子聚合能夠產(chǎn)生新的桶,然后可以添加到父桶中。 基

    2024年02月06日
    瀏覽(15)

覺得文章有用就打賞一下文章作者

支付寶掃一掃打賞

博客贊助

微信掃一掃打賞

請作者喝杯咖啡吧~博客贊助

支付寶掃一掃領(lǐng)取紅包,優(yōu)惠每天領(lǐng)

二維碼1

領(lǐng)取紅包

二維碼2

領(lǐng)紅包