1. 程式人生 > >elasticsearch2.x中es-sql的distinct欄位和原生的cardinality使用及適用場景

elasticsearch2.x中es-sql的distinct欄位和原生的cardinality使用及適用場景

場景:

        使用者通過資料集dataset分組,並通過event_no欄位去重進行資料去重後統計。

使用es-sql實現等價去重查詢:

SELECT dataset,count(DISTINCT event_no) as count from json_archives_qc/info group by dataset

為什麼我要說類似等價呢? 因為從精確性、效能等角度還是和普通sql有很大區別的~!!!

使用cardinality聚合函式(只支援40000以內統計結果的精確度

dsl:

{
	"from": 0,
	"size": 0,
	"fields": "dataset",
	"aggregations": {
		"dataset": {
			"terms": {
				"field": "dataset",
				"size": 200
			},
			"aggregations": {
				"count": {
					"cardinality": {
						"field": "event_no",
						"precision_threshold": 40000
					}
				}
			}
		}
	}
}

詳細程式碼:

        SearchRequestBuilder builder = transportClient.prepareSearch("json_archives_qc");
            builder.setTypes("info");
            builder.setSearchType(SearchType.DFS_QUERY_THEN_FETCH);
            AggregationBuilder terms = AggregationBuilders.terms("dataset").field("dataset").size(200);
            CardinalityBuilder childTerms = AggregationBuilders.cardinality("count").field("event_no").precisionThreshold(40000);
            terms.subAggregation(childTerms);
            builder.addAggregation(terms);
            builder.setSize(0);
            builder.setFrom(0);
            SearchResponse response = builder.get();
            StringTerms longTerms = response.getAggregations().get("dataset");
            for (Terms.Bucket item : longTerms.getBuckets()) {
                InternalCardinality extendedStats = item.getAggregations().get("count");
                Map<String, Object> temp = new HashMap<>();
                temp.put("dataset", item.getKeyAsString());
                temp.put("count", extendedStats.getValue());
                resultList.add(temp);
                num1 += extendedStats.getValue();
            }

主要程式碼:InternalCardinality extendedStats = item.getAggregations().get("count"); //獲取去重過濾後的統計結果;  需要使用InternalCardinality 進行獲取資料, 之前直接通過item.getAggregations().get("count") 去獲取去重後結果,一直無法獲取成功;

  優點:效能快,億級別的記錄在1秒內完成

  缺點:返回結果只能保證最大40000條記錄的精確,統計結果超過40000的話會存在5%的誤差,不適合需要精確去重場景

精度要求場景:

未研究哈,後續繼續研究下,有問題的同學可以留言互相探討