Elasticsearch Distinct Count 구하기 (Cardinality Aggs는 사용하지 마세요!)

조갱·2022년 11월 20일
1

ElasticSearch

목록 보기
7/7
post-thumbnail

Elasticsearch 에서 distinct한 count를 구하고 싶을 때가 있다.

MySQL 쿼리로 치면

SELECT COUNT(1)
FROM (
  SELECT SomeField1, SomeField2, SomeField3
  FROM SomeTable
  WHERE SomeCondition
  GROUP BY SomeField1, SomeField2, SomeField3
) AS TMP

같은 느낌이다.

Cardinality Aggregation

ES에서는 Cardinality Aggregation을 제공하는데, 이거 참 위험하다.
공식 문서를 살펴보면, 아래와 같은 설명이 있다.

Counts are approximate
Computing exact counts requires loading values into a hash set and returning its size. This doesn’t scale when working on high-cardinality sets and/or large values as the required memory usage and the need to communicate those per-shard sets between nodes would utilize too many resources of the cluster.

This cardinality aggregation is based on the HyperLogLog++ algorithm, which counts based on the hashes of the values with some interesting properties:

간략하게 해석해보자면, HashSet을 활용해 정확한 개수를 계산하는 것은 클러스터의 자원을 너무 많이 먹어요~ 그래서 Cardinality Aggs는 HyperLogLog++ 알고리즘에 기반하여 대략적인 값을 반환해요~이다.

문제 상황

사용하는 목적에 따라 다르겠지만, 나는 통계 작업에 사용했기 때문에, 대략적인 값을 반환 은 절대 허용되지 않는 상황이었다.

실무에서 사용하는 쿼리이기 때문에 공개는 못하지만, 결과만 보자.
정상 : 315개 이지만,
cardinality Aggs를 통해 나온 결과는 314개이다.

해결 방법

해결한 방법

Accurate Distinct Count and Values from Elasticsearch.

script를 활용해서 HashSet으로 Distinct value count를 구하는 방법이다. 메모리는 많이 먹겠지만 정확하다. (따라서 최소한의 필드로 distinct count를 구해야한다.)

그 외에도 cardinality aggs와 script를 사용했을 때 응답하는 count를 비교하는 자료가 있으니 꼭 참고해보면 좋겠다.

해결은 못했지만 시도했던 방법

  • 내가 모르고 있던 (Exact Distinct Value Count를 구하는) ES의 기능이 있지 않을까?
    • 그런 방법은 없었다.
  • 위 사진에서 termsAggs의 bucket 사이즈를 구하는 방법
    • 클라이언트에서 구현은 가능하지만,
    • 클라이언트의 메모리도 많이 먹고
    • 최대 bucket 사이즈가 넘어갈 수도 있다.
    • 즉 우아한 방법은 아니다.
  • Cardinality Aggs의 precision_threshold 옵션을 조정하면?
    • 최대 (40,000)로 조정해도 안된다.

지금까지 준비했던 ES 시리즈는 끝이다.
애초에 실무에서 ES쿼리를 작성하면서 겪었던 이슈를 공유하는게 목적이었기 때문에,
기본적인 쿼리의 사용법은 많이 뛰어넘었다. (기본적인 사용방법은 공식 문서가 최고다.)

앞으로는 Spring-Data-Elasticsearch 를 사용하며 Spring 환경에서 겪었던 이슈에 대해 소개해보자 한다.

Reference
https://www.elastic.co/guide/en/elasticsearch/reference/current/search-aggregations-metrics-cardinality-aggregation.html
https://pratik-patil.medium.com/accurate-distinct-count-and-values-from-elasticsearch-dadce51ad4a7

profile
A fast learner.

0개의 댓글