컬렉션 함수

컬렉션 함수 (Collection Functions)

컬렉션 함수는 데이터의 배열과 다중값(multivalue) 필드를 생성·조작·분석해요. 복잡한 데이터 구조를 다루고 배열 요소를 필터링·변환·분석하는 작업에 필수적이에요.

출처: 문서

본문

컬렉션 함수는 데이터의 배열과 다중값 필드를 생성하고, 조작하고, 분석해요. 복잡한 데이터 구조를 다루고 배열 요소를 필터링·변환·분석하는 작업에 필수적이에요.

PPL에서 지원하는 컬렉션 함수는 다음과 같아요.

ARRAY

사용법: array(value1, value2, value3...)

입력 값을 포함하는 배열을 만들어요. 혼합 타입은 가장 덜 제한적인 타입으로 자동 변환돼요. 예를 들어 array(1, "demo")는 정수가 문자열로 변환된 ["1", "demo"]를 반환해요.

매개변수:

  • value1 (필수): 배열에 포함할 모든 타입의 값이에요.
  • value2, value3 (선택): 배열에 포함할 모든 타입의 추가 값이에요.

반환 타입: ARRAY

예제

다음 예제는 숫자 값으로 배열을 만들어요:

source=people
| eval array = array(1, 2, 3)
| fields array
| head 1

쿼리는 다음과 같은 결과를 반환해요:

array
[1,2,3]

다음 예제는 혼합 타입 변환을 보여줘요:

source=people
| eval array = array(1, "demo")
| fields array
| head 1

쿼리는 다음과 같은 결과를 반환해요:

array
[1,demo]

ARRAY_LENGTH

사용법: array_length(array)

입력 배열의 길이를 반환해요.

매개변수:

  • array (필수): 길이를 반환할 배열이에요.

반환 타입: INTEGER

예제
source=people
| eval array = array(1, 2, 3)
| eval length = array_length(array)
| fields length
| head 1

쿼리는 다음과 같은 결과를 반환해요:

length
3

FORALL

사용법: forall(array, function)

배열의 모든 요소가 람다 함수 조건을 만족하는지 확인해요. 람다 함수는 단일 입력 매개변수를 받고 불리언 값을 반환해야 해요.

매개변수:

  • array (필수): 확인할 배열이에요.
  • function (필수): 불리언 값을 반환하고 단일 입력 매개변수를 받는 람다 함수예요.

반환 타입: BOOLEAN

예제
source=people
| eval array = array(1, 2, 3), result = forall(array, x -> x > 0)
| fields result
| head 1

쿼리는 다음과 같은 결과를 반환해요:

result
True

EXISTS

사용법: exists(array, function)

배열의 요소 중 적어도 하나가 람다 함수 조건을 만족하는지 확인해요. 람다 함수는 단일 입력 매개변수를 받고 불리언 값을 반환해야 해요.

매개변수:

  • array (필수): 확인할 배열이에요.
  • function (필수): 불리언 값을 반환하고 단일 입력 매개변수를 받는 람다 함수예요.

반환 타입: BOOLEAN

예제
source=people
| eval array = array(-1, -2, 3), result = exists(array, x -> x > 0)
| fields result
| head 1

쿼리는 다음과 같은 결과를 반환해요:

result
True

FILTER

사용법: filter(array, function)

람다 함수를 사용해 배열의 요소를 필터링해요. 람다 함수는 단일 입력 매개변수를 받고 불리언 값을 반환해야 해요.

매개변수:

  • array (필수): 필터링할 배열이에요.
  • function (필수): 불리언 값을 반환하고 단일 입력 매개변수를 받는 람다 함수예요.

반환 타입: ARRAY

예제
source=people
| eval array = array(1, -2, 3), result = filter(array, x -> x > 0)
| fields result
| head 1

쿼리는 다음과 같은 결과를 반환해요:

result
[1,3]

TRANSFORM

사용법: transform(array, function)

람다 함수를 사용해 배열의 요소를 하나씩 변환해요. 람다 함수는 하나 또는 두 개의 입력을 받을 수 있어요. 람다 함수가 두 개의 매개변수를 받으면 두 번째 매개변수는 배열에서 요소의 인덱스예요.

매개변수:

  • array (필수): 변환할 배열이에요.
  • function (필수): 하나 또는 두 개의 입력 매개변수를 받고 변환된 값을 반환하는 람다 함수예요.

반환 타입: ARRAY

예제

다음 예제는 각 요소에 2를 더해 변환해요:

source=people
| eval array = array(1, -2, 3), result = transform(array, x -> x + 2)
| fields result
| head 1

쿼리는 다음과 같은 결과를 반환해요:

result
[3,0,5]

다음 예제는 변환에 요소 값과 인덱스를 모두 사용해요:

source=people
| eval array = array(1, -2, 3), result = transform(array, (x, i) -> x + i)
| fields result
| head 1

쿼리는 다음과 같은 결과를 반환해요:

result
[1,-1,5]

REDUCE

사용법: reduce(array, acc_base, function, <reduce_function>)

람다 함수를 사용해 모든 요소를 반복하면서 누적기(accumulator) 기본 값과 상호작용해요. 람다 함수는 누적기와 배열 요소 두 개의 매개변수를 받아요. 선택적 reduce_function이 제공되면 최종 누적기 값에 적용돼요. reduce 함수는 누적기를 단일 매개변수로 받아요.

매개변수:

  • array (필수): 줄일 배열이에요.
  • acc_base (필수): 초기 누적기 값이에요.
  • function (필수): 누적기와 배열 요소를 매개변수로 받는 람다 함수예요.
  • reduce_function (선택): 최종 누적기 값에 적용할 람다 함수예요.

반환 타입: 누적기 타입과 동일 (acc_base와 reduce_function에 의해 결정됨)

예제

다음 예제는 초기 값으로 배열을 줄여 모든 요소를 합산해요:

source=people
| eval array = array(1, -2, 3), result = reduce(array, 10, (acc, x) -> acc + x)
| fields result
| head 1

쿼리는 다음과 같은 결과를 반환해요:

result
12

다음 예제는 추가 reduce 함수를 사용해 최종 결과를 변환해요:

source=people
| eval array = array(1, -2, 3), result = reduce(array, 10, (acc, x) -> acc + x, acc -> acc * 10)
| fields result
| head 1

쿼리는 다음과 같은 결과를 반환해요:

result
120

MVJOIN

사용법: mvjoin(array, delimiter)

문자열 배열 요소를 지정된 구분자로 구분된 단일 문자열로 결합해요. NULL 요소는 출력에서 제외돼요. 문자열 배열만 지원돼요.

매개변수:

  • array (필수): 결합할 문자열 배열이에요.
  • delimiter (필수): 배열 요소 사이의 구분자로 사용할 문자열이에요.

반환 타입: STRING

예제

다음 예제는 문자열 배열을 쉼표 구분자로 결합해요:

source=people
| eval result = mvjoin(array('a', 'b', 'c'), ',')
| fields result
| head 1

쿼리는 다음과 같은 결과를 반환해요:

result
a,b,c

다음 예제는 필드 값을 단일 문자열로 결합해요:

source=accounts
| eval names_array = array(firstname, lastname)
| eval result = mvjoin(names_array, ', ')
| fields result
| head 1

쿼리는 다음과 같은 결과를 반환해요:

result
Amber, Duke

MVAPPEND

사용법: mvappend(value1, value2, value3...)

매개변수의 모든 요소를 추가해 배열을 만들어요. 배열 매개변수를 평탄화(flatten)하고 모든 개별 요소를 수집해요. 일관된 타입 동작을 위해 항상 배열 또는 NULL을 반환해요.

매개변수:

  • value1 (필수): 배열에 추가할 모든 타입의 값이에요.
  • value2 (선택): 배열에 추가할 모든 타입의 추가 값이에요.
  • ... (선택): 원하는 만큼의 추가 값이에요.

반환 타입: ARRAY

예제

다음 예제는 여러 값을 추가해 배열을 만들어요:

source=people
| eval result = mvappend(1, 1, 3)
| fields result
| head 1

쿼리는 다음과 같은 결과를 반환해요:

result
[1,1,3]

다음 예제는 배열 평탄화를 보여줘요:

source=people
| eval result = mvappend(1, array(2, 3))
| fields result
| head 1

쿼리는 다음과 같은 결과를 반환해요:

result
[1,2,3]

다음 예제는 중첩 mvappend 호출을 보여줘요:

source=people
| eval result = mvappend(mvappend(1, 2), 3)
| fields result
| head 1

쿼리는 다음과 같은 결과를 반환해요:

result
[1,2,3]

다음 예제는 단일 값으로 배열을 만들어요:

source=people
| eval result = mvappend(42)
| fields result
| head 1

쿼리는 다음과 같은 결과를 반환해요:

result
[42]

다음 예제는 NULL 값 필터링을 보여줘요:

source=people
| eval result = mvappend(nullif(1, 1), 2)
| fields result
| head 1

쿼리는 다음과 같은 결과를 반환해요:

result
[2]

다음 예제는 NULL 값만 있을 때의 동작을 보여줘요:

source=people
| eval result = mvappend(nullif(1, 1))
| fields result
| head 1

쿼리는 다음과 같은 결과를 반환해요:

result
null

다음 예제는 여러 배열을 연결해요:

source=people
| eval arr1 = array(1, 2), arr2 = array(3, 4), result = mvappend(arr1, arr2)
| fields result
| head 1

쿼리는 다음과 같은 결과를 반환해요:

result
[1,2,3,4]

다음 예제는 필드 값을 추가해요:

source=accounts
| eval result = mvappend(firstname, lastname)
| fields result
| head 1

쿼리는 다음과 같은 결과를 반환해요:

result
[Amber,Duke]

다음 예제는 혼합 데이터 타입을 보여줘요:

source=people
| eval result = mvappend(1, 'text', 2.5)
| fields result
| head 1

쿼리는 다음과 같은 결과를 반환해요:

result
[1,text,2.5]

SPLIT

사용법: split(str, delimiter)

구분자로 문자열 값을 분할하고 문자열 값을 다중값 필드(배열)로 반환해요. 빈 문자열("")을 사용하면 원래 문자열을 문자 하나씩으로 분할해요. 구분자를 찾지 못하면 원래 문자열을 포함하는 배열을 반환해요. 입력 문자열이 비어 있으면 빈 배열을 반환해요.

매개변수:

  • str (필수): 분할할 문자열이에요.
  • delimiter (필수): 분할에 사용할 구분자 문자열이에요.

반환 타입: ARRAY

예제

다음 예제는 세미콜론 구분자로 문자열을 분할해요:

source=people
| eval test = 'buttercup;rarity;tenderhoof;dash', result = split(test, ';')
| fields result
| head 1

쿼리는 다음과 같은 결과를 반환해요:

result
[buttercup,rarity,tenderhoof,dash]

다음 예제는 다중 문자 구분자를 사용해요:

source=people
| eval test = '1a2b3c4def567890', result = split(test, 'def')
| fields result
| head 1

쿼리는 다음과 같은 결과를 반환해요:

result
[1a2b3c4,567890]

다음 예제는 빈 구분자로 문자열을 개별 문자로 분할해요:

source=people
| eval test = 'abcd', result = split(test, '')
| fields result
| head 1

쿼리는 다음과 같은 결과를 반환해요:

result
[a,b,c,d]

다음 예제는 이중 콜론 구분자로 분할해요:

source=people
| eval test = 'name::value', result = split(test, '::')
| fields result
| head 1

쿼리는 다음과 같은 결과를 반환해요:

result
[name,value]

다음 예제는 구분자를 찾지 못했을 때의 동작을 보여줘요:

source=people
| eval test = 'hello', result = split(test, ',')
| fields result
| head 1

쿼리는 다음과 같은 결과를 반환해요:

result
[hello]

MVDEDUP

사용법: mvdedup(array)

다중값 배열에서 중복 값을 제거하면서 첫 번째 발생 순서를 보존해요. NULL 요소는 필터링돼요. 중복 제거된 배열을 반환하며, 입력이 NULL이면 NULL을 반환해요.

매개변수:

  • array (필수): 중복을 제거할 배열이에요.

반환 타입: ARRAY

예제

다음 예제는 순서를 보존하며 중복 숫자를 제거해요:

source=people
| eval array = array(1, 2, 2, 3, 1, 4), result = mvdedup(array)
| fields result
| head 1

쿼리는 다음과 같은 결과를 반환해요:

result
[1,2,3,4]

다음 예제는 문자열 값을 중복 제거해요:

source=people
| eval array = array('z', 'a', 'z', 'b', 'a', 'c'), result = mvdedup(array)
| fields result
| head 1

쿼리는 다음과 같은 결과를 반환해요:

result
[z,a,b,c]

다음 예제는 빈 배열일 때의 동작을 보여줘요:

source=people
| eval array = array(), result = mvdedup(array)
| fields result
| head 1

쿼리는 다음과 같은 결과를 반환해요:

result
[]

MVFIND

사용법: mvfind(array, regex)

다중값 배열을 검색하고 정규 표현식과 일치하는 첫 번째 요소의 0 기반 인덱스를 반환해요. 일치하는 것이 없으면 NULL을 반환해요.

매개변수:

  • array (필수): 검색할 배열이에요.
  • regex (필수): 배열 요소와 대조할 정규 표현식 패턴이에요.

반환 타입: INTEGER (일치 항목이 없으면 NULL)

예제

다음 예제는 정규 표현식과 일치하는 첫 번째 요소를 검색해요:

source=people
| eval array = array('apple', 'banana', 'apricot'), result = mvfind(array, 'ban.*')
| fields result
| head 1

쿼리는 다음과 같은 결과를 반환해요:

result
1

다음 예제는 일치 항목이 없을 때의 동작을 보여줘요:

source=people
| eval array = array('cat', 'dog', 'bird'), result = mvfind(array, 'fish')
| fields result
| head 1

쿼리는 다음과 같은 결과를 반환해요:

result
null

다음 예제는 문자 클래스를 가진 정규 표현식 패턴을 사용해요:

source=people
| eval array = array('error123', 'info', 'error456'), result = mvfind(array, 'error[0-9]+')
| fields result
| head 1

쿼리는 다음과 같은 결과를 반환해요:

result
0

다음 예제는 대소문자 무시 매칭을 보여줘요:

source=people
| eval array = array('Apple', 'Banana', 'Cherry'), result = mvfind(array, '(?i)banana')
| fields result
| head 1

쿼리는 다음과 같은 결과를 반환해요:

result
1

MVINDEX

사용법: mvindex(array, start, [end])

시작 인덱스와 선택적 종료 인덱스를 사용해 다중값 배열의 하위 집합을 반환해요. 인덱스는 0 기반이에요 (첫 번째 요소는 인덱스 0). -1이 마지막 요소를 가리키는 음수 인덱싱을 지원해요. start만 제공하면 단일 요소를 반환해요. start와 end를 모두 제공하면 start부터 end까지(포함)의 요소 배열을 반환해요.

매개변수:

  • array (필수): 요소를 추출할 배열이에요.
  • start (필수): 시작 인덱스 (0 기반)예요.
  • end (선택): 종료 인덱스 (0 기반, 포함)예요.

반환 타입: start만 제공하면 단일 요소 타입; start와 end를 모두 제공하면 ARRAY

예제

다음 예제는 인덱스 1의 단일 요소를 가져와요:

source=people
| eval array = array('a', 'b', 'c', 'd', 'e'), result = mvindex(array, 1)
| fields result
| head 1

쿼리는 다음과 같은 결과를 반환해요:

result
b

다음 예제는 음수 인덱싱으로 마지막 요소를 가져와요:

source=people
| eval array = array('a', 'b', 'c', 'd', 'e'), result = mvindex(array, -1)
| fields result
| head 1

쿼리는 다음과 같은 결과를 반환해요:

result
e

다음 예제는 요소 범위를 추출해요:

source=people
| eval array = array(1, 2, 3, 4, 5), result = mvindex(array, 1, 3)
| fields result
| head 1

쿼리는 다음과 같은 결과를 반환해요:

result
[2,3,4]

다음 예제는 범위에 음수 인덱싱을 사용해요:

source=people
| eval array = array(1, 2, 3, 4, 5), result = mvindex(array, -3, -1)
| fields result
| head 1

쿼리는 다음과 같은 결과를 반환해요:

result
[3,4,5]

다음 예제는 배열의 처음부터 요소를 추출해요:

source=people
| eval array = array('alex', 'celestino', 'claudia', 'david'), result = mvindex(array, 0, 2)
| fields result
| head 1

쿼리는 다음과 같은 결과를 반환해요:

result
[alex,celestino,claudia]

MVMAP

사용법: mvmap(array, expression)

다중값 배열의 각 요소를 반복하고 각 요소에 표현식을 적용한 뒤 변환 결과를 담은 다중값 배열을 반환해요. 표현식의 필드 이름은 각 요소 값에 암시적으로 바인딩돼요.

매개변수:

  • array (필수): 매핑할 배열이에요.
  • expression (필수): 각 요소에 적용할 표현식이에요.

반환 타입: ARRAY

예제

다음 예제는 배열의 각 요소에 수학 연산을 적용해요:

source=people
| eval array = array(1, 2, 3), result = mvmap(array, array * 10)
| fields result
| head 1

쿼리는 다음과 같은 결과를 반환해요:

result
[10,20,30]

다음 예제는 다른 수학 연산을 적용해요:

source=people
| eval array = array(1, 2, 3), result = mvmap(array, array + 5)
| fields result
| head 1

쿼리는 다음과 같은 결과를 반환해요:

result
[6,7,8]

mvmap(mvindex(arr, 1, 3), arr * 2) 같은 중첩 표현식에서는 필드 이름(arr)이 첫 번째 인수에서 추출되며 표현식에서 참조한 필드와 일치해야 해요.

다음 예제는 표현식이 다른 단일 값 필드를 참조하는 방법을 보여줘요:

source=people
| eval array = array(1, 2, 3), multiplier = 10, result = mvmap(array, array * multiplier)
| fields result
| head 1

쿼리는 다음과 같은 결과를 반환해요:

result
[10,20,30]

MVZIP

사용법: mvzip(mv_left, mv_right, [delim])

두 다중값 배열의 값을 대응하는 요소끼리 짝지어 문자열로 결합해요. 구분자는 두 값을 연결하는 데 사용되는 문자 또는 문자열을 지정해요. Python의 zip 명령과 유사해요.

값은 mv_left의 첫 번째 값과 mv_right의 첫 번째 값, 두 번째와 두 번째 식으로 짝지어 결합돼요. 각 쌍은 구분자를 사용해 문자열로 연결돼요. 함수는 더 짧은 배열의 길이에서 멈춰요.

구분자는 선택 사항이에요. 지정하면 따옴표로 묶어야 해요. 기본 구분자는 쉼표예요.

두 입력 중 하나가 NULL이면 NULL을 반환해요. 입력 배열 중 하나가 비어 있으면 빈 배열을 반환해요.

매개변수:

  • mv_left (필수): 결합할 첫 번째 배열이에요.
  • mv_right (필수): 결합할 두 번째 배열이에요.
  • delim (선택): 쌍을 연결하는 데 사용할 구분자예요. 기본값은 쉼표예요.

반환 타입: ARRAY

예제

다음 예제는 host와 port 배열을 콜론 구분자로 결합해요:

source=people
| eval hosts = array('host1', 'host2'), ports = array('80', '443'), nserver = mvzip(hosts, ports, ':')
| fields nserver
| head 1

쿼리는 다음과 같은 결과를 반환해요:

nserver
[host1:80,host2:443]

다음 예제는 같은 길이의 배열에 파이프 구분자를 사용해요:

source=people
| eval arr1 = array('a', 'b', 'c'), arr2 = array('x', 'y', 'z'), result = mvzip(arr1, arr2, '|')
| fields result
| head 1

쿼리는 다음과 같은 결과를 반환해요:

result |  |  | 
[a | x,b | y,c | z]

다음 예제는 길이가 다른 배열의 동작을 보여줘요:

source=people
| eval arr1 = array('1', '2', '3'), arr2 = array('a', 'b'), result = mvzip(arr1, arr2, '-')
| fields result
| head 1

쿼리는 다음과 같은 결과를 반환해요:

result
[1-a,2-b]

다음 예제는 중첩 mvzip 호출을 보여줘요:

source=people
| eval arr1 = array('a', 'b', 'c'), arr2 = array('x', 'y', 'z'), arr3 = array('1', '2', '3'), result = mvzip(mvzip(arr1, arr2, '-'), arr3, ':')
| fields result
| head 1

쿼리는 다음과 같은 결과를 반환해요:

result
[a-x:1,b-y:2,c-z:3]

다음 예제는 빈 배열일 때의 동작을 보여줘요:

source=people
| eval arr1 = array('a', 'b'), arr2 = array(), result = mvzip(arr1, arr2)
| fields result
| head 1

쿼리는 다음과 같은 결과를 반환해요:

result
[]

더 알아보기 (Learn more)