Post-aggregations

Post-aggregations (포스트 집계)

Post-aggregation은 Apache Druid에서 집계된 값이 나온 뒤에 수행할 처리를 지정하는 스펙이에요. 집계 결과를 합치고 변환해 최종 값을 만드는 데 사용해요.

출처: 문서

본문

Apache Druid는 두 가지 쿼리 언어를 지원해요: Druid SQL 과 native 쿼리. 이 문서는 native 언어를 설명해요. SQL에서 사용 가능한 함수에 대한 정보는 SQL 문서 를 참고하세요.

Post-aggregation은 Apache Druid에서 나오는 집계 값에 대해 수행할 처리를 지정하는 스펙이에요. 쿼리의 일부로 post-aggregation을 포함한다면, post-aggregator가 필요로 하는 모든 집계자를 포함해야 해요.

여러 post-aggregator가 있어요.

산술 post-aggregator (Arithmetic post-aggregator)

산술 post-aggregator는 제공된 함수를 주어진 필드들에 왼쪽에서 오른쪽으로 적용해요. 필드는 집계자 또는 다른 post-aggregator일 수 있어요.

| 속성 | 설명 | 필수 | | type | 반드시 "arithmetic"이어야 해요. | 예 | | name | post-aggregation의 출력 이름 | 예 | | fn | 지원되는 함수는 +, -, *, /, pow, quotient 예요. | 예 | | fields | fn의 입력을 정의하는 post-aggregator 스펙 목록 | 예 | | ordering | ordering(또는 null)을 지정하지 않으면 기본 부동소수점 ordering이 사용돼요. numericFirst ordering은 항상 유한 값을 먼저, 그다음 NaN, 마지막에 무한 값을 반환해요. | 아니요 |

참고:

  • / 나눗셈은 분자에 상관없이 0으로 나누면 항상 0을 반환해요.
  • quotient 나눗셈은 일반 부동소수점 나눗셈처럼 동작해요.
  • 산술 post-aggregator는 항상 부동소수점 산술을 사용해요.

예시:

{
  "type"  : "arithmetic",
  "name"  : "mult",
  "fn"    : "*",
  "fields": [
    {"type": "fieldAccess", "fieldName":  "someAgg"},
    {"type": "fieldAccess", "fieldName":  "someOtherAgg"}
  ]
}

필드 접근자 post-aggregator (Field accessor post-aggregators)

이 post-aggregator들은 지정된 차원 또는 집계자 가 생성한 값을 반환해요.

| 속성 | 설명 | 필수 | | type | 반드시 "fieldAccess" 또는 "finalizingFieldAccess"이어야 해요. 타입 "fieldAccess"는 원시 집계 객체를, "finalizingFieldAccess"는 추정 카디널리티 같은 확정(finalized) 값을 반환해요. | 예 | | name | post-aggregation의 출력 이름 | standalone post-aggregation으로 정의되면 예, 그러나 다른 post-aggregator의 fields 목록에 인라인으로 사용되면 생략할 수 있어요. | | fieldName | 참조할 차원 또는 집계자의 출력 이름 | 예 |

예시:

{ "type" : "fieldAccess", "name": "someField", "fieldName" : "someAggregator" }

또는

{ "type" : "finalizingFieldAccess", "name": "someFinalizedField", "fieldName" : "someAggregator" }

상수 post-aggregator (Constant post-aggregator)

상수 post-aggregator는 항상 지정된 값을 반환해요.

| 속성 | 설명 | 필수 | | type | 반드시 "constant"이어야 해요. | 예 | | name | post-aggregation의 출력 이름 | 예 | | value | 상수 값 | 예 |

예시:

{ "type"  : "constant", "name"  : "someConstant", "value" : 1234 }

표현식 post-aggregator (Expression post-aggregator)

표현식 post-aggregator는 Druid expression 으로 정의돼요.

| 속성 | 설명 | 필수 | | type | 반드시 "expression"이어야 해요. | 예 | | name | post-aggregation의 출력 이름 | 예 | | expression | 계산할 native Druid 표현식. 어떤 차원 또는 집계자 출력 이름도 참조할 수 있어요. | 예 | | ordering | ordering(또는 null)을 지정하지 않으면 "natural" ordering이 사용돼요. numericFirst ordering은 항상 유한 값을 먼저, 그다음 NaN, 마지막에 무한 값을 반환해요. 표현식이 배열이나 복합 타입을 생성하면 ordering을 null로 지정하고 올바른 타입 native ordering을 사용하려면 outputType을 대신 사용하세요. | 아니요 | | outputType | 출력 타입은 선택사항이며 LONG, FLOAT, DOUBLE, STRING, ARRAY 타입(예: ARRAY<LONG>), 또는 COMPLEX 타입(예: COMPLEX<json>) 같은 어떤 native Druid 타입도 될 수 있어요. 지정하지 않으면 출력 타입이 expression 에서 추론돼요. 지정되고 ordering이 null이면 값 정렬에 타입 native ordering이 사용돼요. 표현식이 배열이나 복합 타입을 생성하면 올바른 정렬을 보장하려면 이 값이 반드시 non-null이어야 해요. outputType이 표현식 의 실제 출력 타입과 일치하지 않으면, 값을 지정된 타입으로 강제 변환하려 시도하고 변환이 불가능하면 실패할 수 있어요. | 아니요 |

예시:

{
  "type": "expression",
  "name": "someExpression",
  "expression": "someAgg + someOtherAgg",
  "ordering": null,
  "outputType": "LONG"
}

Greatest / Least post-aggregators

doubleGreatest와 longGreatest는 모든 필드와 Double.NEGATIVE_INFINITY의 최댓값을 계산해요. doubleLeast와 longLeast는 모든 필드와 Double.POSITIVE_INFINITY의 최솟값을 계산해요.

| 속성 | 설명 | 필수 | | type | 반드시 "doubleGreatest", "doubleLeast", "longGreatest", 또는 "longLeast"이어야 해요. | 예 | | name | post-aggregation의 출력 이름 | 예 | | fields | greatest 또는 least 함수에 대한 입력을 정의하는 post-aggregator 스펙 목록 | 예 |

doubleMax 집계자와 doubleGreatest post-aggregator의 차이는, doubleMax는 하나의 특정 컬럼에 대한 모든 행의 최댓값을 반환하는 반면 doubleGreatest는 한 행에서 여러 컬럼의 최댓값을 반환한다는 점이에요. 이들은 SQL의 MAX와 GREATEST 함수와 유사해요.

예시:

{
  "type"  : "doubleGreatest",
  "name"  : "theGreatest",
  "fields": [
    { "type": "fieldAccess", "fieldName": "someAgg" },
    { "type": "fieldAccess", "fieldName": "someOtherAgg" }
  ]
}

JavaScript post-aggregator

제공된 JavaScript 함수를 주어진 필드에 적용해요. 필드는 주어진 순서대로 JavaScript 함수의 인자로 전달돼요.

| 속성 | 설명 | 필수 | | type | 반드시 "javascript"이어야 해요. | 예 | | name | post-aggregation의 출력 이름 | 예 | | fieldNames | 입력 차원 또는 집계자 출력 이름 목록 | 예 | | function | fieldNames를 인자로 받는 String JavaScript 함수 | 예 |

예시:

{
  "type": "javascript",
  "name": "someJavascript",
  "fieldNames" : ["someAgg", "someOtherAgg"],
  "function": "function(someAgg, someOtherAgg) { return 100 * Math.abs(someAgg) / someOtherAgg;"
}

:::admonish 참고

JavaScript 기반 기능은 기본적으로 비활성화되어 있어요. Druid JavaScript 기능을 사용하는 지침(활성화 방법 포함)은 Druid JavaScript programming guide 를 참고하세요.


HyperUnique Cardinality post-aggregator

hyperUniqueCardinality post-aggregator는 hyperUnique 객체를 감싸서 post-aggregation에서 사용할 수 있게 해요.

| 속성 | 설명 | 필수 | | type | 반드시 "hyperUniqueCardinality"이어야 해요. | 예 | | name | post-aggregation의 출력 이름 | 예 | | fieldName | hyperUnique 집계자의 출력 이름 | 예 |

{
  "type"  : "hyperUniqueCardinality",
  "name": "someCardinality",
  "fieldName"  : "someHyperunique"
}

샘플 계산에서 이렇게 사용할 수 있어요:

{
  ...
  "aggregations" : [
    {"type" : "count", "name" : "rows"},
    {"type" : "hyperUnique", "name" : "unique_users", "fieldName" : "uniques"}
  ],
  "postAggregations" : [
    {
      "type"   : "arithmetic",
      "name"   : "average_users_per_row",
      "fn"     : "/",
      "fields" : [
        { "type" : "hyperUniqueCardinality", "fieldName" : "unique_users" },
        { "type" : "fieldAccess", "name" : "rows", "fieldName" : "rows" }
      ]
    }
  ]
  ...
}

이 post-aggregator는 참조하는 집계자의 반올림 동작을 상속해요. 이 상속은 집계자를 직접 참조할 때만 유효하다는 점에 유의하세요. 예를 들어 다른 post-aggregator를 거치면 사용자가 지정한 반올림 동작이 손실되고 기본값인 "반올림 없음"으로 돌아가요.

사용 예시 (Example Usage)

이 예시에서는 post-aggregator를 사용해 간단한 백분율을 계산해 볼게요. 데이터셋에 "total"이라는 메트릭이 있다고 상상해 봐요.

쿼리 JSON 형식은 다음과 같아요:

{
  ...
  "aggregations" : [
    { "type" : "count", "name" : "rows" },
    { "type" : "doubleSum", "name" : "tot", "fieldName" : "total" }
  ],
  "postAggregations" : [
    {
      "type"   : "arithmetic",
      "name"   : "average",
      "fn"     : "/",
      "fields" : [
        { "type" : "fieldAccess", "name" : "tot", "fieldName" : "tot" },
        { "type" : "fieldAccess", "name" : "rows", "fieldName" : "rows" }
      ]
    }
  ]
  ...
}
{
  ...
  "aggregations" : [
    { "type" : "doubleSum", "name" : "tot", "fieldName" : "total" },
    { "type" : "doubleSum", "name" : "part", "fieldName" : "part" }
  ],
  "postAggregations" : [
    {
      "type"   : "arithmetic",
      "name"   : "part_percentage",
      "fn"     : "*",
      "fields" : [
        {
          "type"   : "arithmetic",
          "name"   : "ratio",
          "fn"     : "/",
          "fields" : [
            { "type" : "fieldAccess", "name" : "part", "fieldName" : "part" },
            { "type" : "fieldAccess", "name" : "tot", "fieldName" : "tot" }
          ]
        },
        { "type" : "constant", "name": "const", "value" : 100 }
      ]
    }
  ]
  ...
}

같은 계산을 표현식 post-aggregator로도 할 수 있어요:

{
  ...
  "aggregations" : [
    { "type" : "doubleSum", "name" : "tot", "fieldName" : "total" },
    { "type" : "doubleSum", "name" : "part", "fieldName" : "part" }
  ],
  "postAggregations" : [
    {
      "type"       : "expression",
      "name"       : "part_percentage",
      "expression" : "100 * (part / tot)"
    }
  ]
  ...
}

더 알아보기 (Learn more)