regexp_tree 딕셔너리를 사용하면 계층적 정규 표현식 패턴을 기반으로 키와 값을 매핑할 수 있습니다.
이 딕셔너리는 정확한 키 일치보다 정규 표현식 패턴 일치(예: 사용자 에이전트 문자열을 정규 표현식 패턴 매칭으로 분류하는 작업) 조회에 더 최적화되어 있습니다.
이 설정은 정규식 트리 노드 목록으로 구성됩니다. 각 노드는 다음과 같은 구조를 가집니다.
regexp: 노드의 정규 표현식입니다.
attributes: 사용자 정의 딕셔너리 속성(attribute) 목록입니다. 이 예제에는 name과 version 두 개의 속성이 있습니다. 첫 번째 노드는 두 속성을 모두 정의합니다. 두 번째 노드는 name 속성만 정의합니다. version 속성은 두 번째 노드의 자식 노드에서 제공합니다.
속성 값에는 매칭된 정규 표현식의 캡처 그룹을 참조하는 역참조(back reference) 를 포함할 수 있습니다. 예제에서 첫 번째 노드의 version 속성 값은 정규 표현식의 캡처 그룹 (\d+[\.\d]*) 에 대한 역참조 \1 로 구성됩니다. 역참조 번호는 1에서 9까지이며 $1 또는 \1 (번호 1의 경우)처럼 표기합니다. 역참조는 쿼리 실행 중에 매칭된 캡처 그룹으로 치환됩니다.
child nodes: 각자 자신의 attributes와 (필요한 경우) 자식 노드를 가지는 regexp 트리 노드의 자식 목록입니다. 문자열 매칭은 깊이 우선 방식으로 진행됩니다. 어떤 문자열이 regexp 노드와 매칭되면, 딕셔너리는 해당 문자열이 그 노드의 자식 노드와도 매칭되는지 확인합니다. 그렇게 되면, 가장 깊이 매칭된 노드의 attributes가 할당됩니다. 자식 노드의 속성은 동일한 이름을 가진 상위 노드의 속성을 덮어씁니다. YAML 파일에서 child node의 이름은 위 예제의 versions 와 같이 임의로 지정할 수 있습니다.
Regexp 트리 딕셔너리에는 dictGet, dictGetOrDefault, dictGetAll 함수만을 사용해 접근할 수 있습니다. 예를 들면 다음과 같습니다.
이 경우, 먼저 최상위 계층의 두 번째 노드에서 정규식 \d+/tclwebkit(?:\d+[\.\d]*)과 일치합니다.
이후 딕셔너리는 자식 노드를 계속 탐색하여 문자열이 3[12]/tclwebkit에도 일치한다는 것을 확인합니다.
그 결과 속성 name의 값은 (첫 번째 계층에서 정의된) Android가 되고, 속성 version의 값은 (자식 노드에서 정의된) 12가 됩니다.
여러 개의 정규식에 매칭된 값들을 리프 노드의 값뿐만 아니라 함께 반환해야 하는 경우가 있습니다. 이때는 전용 함수 dictGetAll을 사용할 수 있습니다. 어떤 노드가 타입 T의 속성 값을 가지면 dictGetAll은 0개 이상의 값을 포함하는 Array(T)를 반환합니다.
기본적으로 키마다 반환되는 매치(일치 항목)의 개수에는 상한이 없습니다. 선택적인 네 번째 인수로 상한을 dictGetAll에 전달할 수 있습니다. 배열은 *위상 순서(topological order)*로 채워지며, 이는 자식 노드가 부모 노드보다 앞에 오고, 형제 노드는 소스에 나온 순서를 따른다는 의미입니다.
YAMLRegExpTree 소스는 ClickHouse 오픈 소스에서는 동작하지만 ClickHouse Cloud에서는 동작하지 않습니다.
ClickHouse Cloud에서 regexp 트리 딕셔너리를 사용하려면, 먼저 ClickHouse 오픈 소스에서 YAML 파일을 사용해 로컬에 regexp 트리 딕셔너리를 생성한 다음, dictionary 테이블 함수와 INTO OUTFILE 절을 사용하여 이 딕셔너리를 CSV 파일로 내보냅니다.
SELECT * FROM dictionary(regexp_dict) INTO OUTFILE('regexp_dict.csv')
CSV 파일의 내용은 다음과 같습니다.
1,0,"Linux/(\d+[\.\d]*).+tlinux","['version','name']","['\\1','TencentOS']"
2,0,"(\d+)/tclwebkit(\d+[\.\d]*)","['comment','version','name']","['test $1 and $2','$1','Android']"
3,2,"33/tclwebkit","['version']","['13']"
4,2,"3[12]/tclwebkit","['version']","['12']"
5,2,"3[12]/tclwebkit","['version']","['11']"
6,2,"3[12]/tclwebkit","['version']","['10']"
덤프된 파일의 스키마는 다음과 같습니다.
id UInt64: RegexpTree 노드의 id입니다.
parent_id UInt64: 노드의 부모 id입니다.
regexp String: 정규표현식 문자열입니다.
keys Array(String): 사용자 정의 속성 이름입니다.
values Array(String): 사용자 정의 속성 값입니다.
ClickHouse Cloud에서 딕셔너리를 생성하려면, 먼저 아래 테이블 구조로 regexp_dictionary_source_table 테이블을 생성합니다.