(九)elasticsearch之分組去重(collapse)

一、背景介紹

問題一:如何對elasticsearch的檢索結果進行去重統計計數。類似mysql 的 select count(*) from a group by b。

問題二:如何對elasticsearch的檢索結果去重後顯示。類似mysql 的select distint(“name”) from a group by b。

二、分析

問題一:

​ 統計計數需要藉助elasticsearch聚合功能結合cardinality實現。

問題二:

​ 方式一:使用字段聚合+top_hots聚合方式。

​ 方式二:使用collapse摺疊功能。

三、DSL 實例

問題一:

// 統計去重數目
GET user/_search
{
    "size":0,
    "aggs" : {
        "name_count" : {
            "cardinality" : {
            	"field" : "name"
            }
        }
    }
}

問題二:

方式一:top_hits 聚合

GET user/_search
{
    "query": {
        "match_all": {
            
        }
    },
    "aggs": {
        "type": {
            "terms": {
                "field": "name",
                "size": 10
            },
            "aggs": {
                "title_top": {
                    "top_hits": {
                        "_source": {
                            "includes": [
                                "name"
                            ]
                        },
                        "sort": [
                            {
                                "name": {
                                    "order": "desc"
                                }
                            }
                        ],
                        "size": 1
                    }
                }
            }
        }
    },
    "size": 0
}

方式二:使用 collapse 摺疊

GET user/_search
{
    "query": {
    	"match_all":{}
    },
    "collapse": {
    	"field": "name"
    }
}

總結:collapse 摺疊比聚合更加簡潔,性能也更加優異。

四、collapse(摺疊)介紹

1、Field Collapsing(字段摺疊)不能與scroll、rescore以及search after 結合使用。

2、使用collapse 的字段如果是 string類型,則es 中對應 keyword。(The field used for collapsing must be a single valued keyword or numeric field with doc_values activated)

3、查看collapse 結果

(1)GET user/_search
{
    "query": {
        "match": {
            "address": "Place"
        }
 	},
    "collapse" : {
        "field" : "age" 
 	},
    "sort": ["age"], 
    "from": 10
}
  
(2)Expand collapse results(對於每個摺疊的結果,可以通過inner_hits展開結果)
   // 單個inner_hits
	GET user/_search
    {
        "query": {
            "match": {
                "address": "Place"
            }
        },
        "collapse" : {
            "field" : "age", 
            "inner_hits": {
                "name": "test", 
                "size": 5, 
                "sort": [{ "age": "asc" }] 
            },
            "max_concurrent_group_searches": 4 
        },
        "sort": ["age"]
    }
    
    // 多個inner_hits
    GET user/_search
    {
        "query": {
            "match": {
                "address": "Place"
            }
        },
        "collapse" : {
            "field" : "age", 
            "inner_hits":[ {
                "name": "age", 
                "size": 2, 
                "sort": [{ "age": "asc" }] 
            },
            {
            "name":"account_number",
            "size": 2, 
            "sort": [{ "account_number": "asc" }] 
            }],
            "max_concurrent_group_searches": 4
        },
        "sort": ["age"]
    }
// max_concurrent_group_searches:允許每組檢索inner_hits的併發請求數 (默認按照線程池的大小或者數據節點數)
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章