메인 콘텐츠로 건너뛰기

개요

regexp_tree 딕셔너리를 사용하면 계층적 정규 표현식 패턴을 기반으로 키를 값에 매핑할 수 있습니다. 정확한 키 일치보다 패턴 일치 조회(예: 정규식 패턴을 매칭해 user agent 문자열과 같은 문자열을 분류하는 작업)에 최적화되어 있습니다.

YAMLRegExpTree 소스로 정규 표현식 트리 딕셔너리 사용하기

정규 표현식 트리 딕셔너리는 정규 표현식 트리가 포함된 YAML 파일의 경로를 받는 YAMLRegExpTree 소스를 사용해 ClickHouse 오픈소스에서 정의합니다.
Query
CREATE DICTIONARY regexp_dict
(
    regexp String,
    name String,
    version String
)
PRIMARY KEY(regexp)
SOURCE(YAMLRegExpTree(PATH '/var/lib/clickhouse/user_files/regexp_tree.yaml'))
LAYOUT(regexp_tree)
...
딕셔너리 소스 YAMLRegExpTree는 regexp 트리 구조를 나타냅니다. 예를 들면 다음과 같습니다:
- regexp: 'Linux/(\d+[\.\d]*).+tlinux'
  name: 'TencentOS'
  version: '\1'

- regexp: '\d+/tclwebkit(?:\d+[\.\d]*)'
  name: 'Android'
  versions:
    - regexp: '33/tclwebkit'
      version: '13'
    - regexp: '3[12]/tclwebkit'
      version: '12'
    - regexp: '30/tclwebkit'
      version: '11'
    - regexp: '29/tclwebkit'
      version: '10'
이 구성은 정규식 트리 노드 목록으로 이루어집니다. 각 노드는 다음 구조를 가집니다.
  • regexp: 노드의 정규식입니다.
  • attributes: 사용자 정의 딕셔너리 속성 목록입니다. 이 예시에는 nameversion이라는 두 개의 속성이 있습니다. 첫 번째 노드는 두 속성을 모두 정의합니다. 두 번째 노드는 name 속성만 정의합니다. version 속성은 두 번째 노드의 자식 노드에서 제공합니다.
    • 속성 값에는 일치한 정규식의 캡처 그룹을 참조하는 역참조가 포함될 수 있습니다. 이 예시에서 첫 번째 노드의 version 속성 값은 정규식의 캡처 그룹 (\d+[\.\d]*)를 참조하는 역참조 \1로 구성됩니다. 역참조 번호는 1부터 9까지이며, $1 또는 \1(숫자 1의 경우)로 작성합니다. 쿼리 실행 중에는 이 역참조가 일치한 캡처 그룹으로 대체됩니다.
  • child nodes: regexp 트리 노드의 자식 목록이며, 각 자식은 자체 속성과 (필요한 경우) 자식 노드를 가집니다. 문자열 일치는 깊이 우선 방식으로 진행됩니다. 문자열이 regexp 노드와 일치하면, 딕셔너리는 해당 문자열이 그 노드의 자식 노드와도 일치하는지 확인합니다. 그럴 경우 가장 깊은 수준에서 일치한 노드의 속성이 할당됩니다. 자식 노드의 속성은 부모 노드의 동일한 이름의 속성을 덮어씁니다. YAML 파일에서 자식 노드의 이름은 임의로 지정할 수 있으며, 위 예시의 versions가 그 예입니다.
regexp 트리 딕셔너리는 dictGet, dictGetOrDefault, dictGetAll 함수로만 접근할 수 있습니다. 예시는 다음과 같습니다:
Query
SELECT dictGet('regexp_dict', ('name', 'version'), '31/tclwebkit1024');
Response
┌─dictGet('regexp_dict', ('name', 'version'), '31/tclwebkit1024')─┐
│ ('Android','12')                                                │
└─────────────────────────────────────────────────────────────────┘
이 경우 먼저 최상위 레이어의 두 번째 노드에서 정규식 \d+/tclwebkit(?:\d+[\.\d]*)와 일치합니다. 그다음 딕셔너리는 하위 노드를 계속 탐색하여 해당 문자열이 3[12]/tclwebkit와도 일치한다는 것을 확인합니다. 그 결과, 속성 name의 값은 Android(첫 번째 레이어에 정의됨)이고 속성 version의 값은 12(하위 노드에 정의됨)입니다. 정교한 YAML 설정 파일을 사용하면 regexp 트리 딕셔너리를 user agent 문자열 파서로 사용할 수 있습니다. ClickHouse는 uap-core를 지원하며, 기능 테스트 02504_regexp_dictionary_ua_parser에서 사용 방법을 확인할 수 있습니다.

속성 값 수집

경우에 따라서는 리프 노드의 값만 반환하는 대신, 일치한 여러 정규식의 값을 함께 반환하는 것이 유용합니다. 이런 경우에는 특수 함수 dictGetAll을 사용할 수 있습니다. 노드에 T 유형의 속성 값이 있으면 dictGetAll은 0개 이상의 값을 담은 Array(T)를 반환합니다. 기본적으로 키별로 반환되는 일치 항목 수에는 제한이 없습니다. 선택적인 네 번째 인수로 반환 개수의 상한을 dictGetAll에 전달할 수 있습니다. 배열은 위상 순서로 채워지며, 이는 자식 노드가 부모 노드보다 먼저 오고 형제 노드는 소스에 있는 순서를 따른다는 뜻입니다. 예시:
CREATE DICTIONARY regexp_dict
(
    regexp String,
    tag String,
    topological_index Int64,
    captured Nullable(String),
    parent String
)
PRIMARY KEY(regexp)
SOURCE(YAMLRegExpTree(PATH '/var/lib/clickhouse/user_files/regexp_tree.yaml'))
LAYOUT(regexp_tree)
LIFETIME(0)
# /var/lib/clickhouse/user_files/regexp_tree.yaml
- regexp: 'clickhouse\.com'
  tag: 'ClickHouse'
  topological_index: 1
  paths:
    - regexp: 'clickhouse\.com/docs(.*)'
      tag: 'ClickHouse Documentation'
      topological_index: 0
      captured: '\1'
      parent: 'ClickHouse'

- regexp: '/docs(/|$)'
  tag: 'Documentation'
  topological_index: 2

- regexp: 'github.com'
  tag: 'GitHub'
  topological_index: 3
  captured: 'NULL'
Query
CREATE TABLE urls (url String) ENGINE=MergeTree ORDER BY url;
INSERT INTO urls VALUES ('clickhouse.com'), ('clickhouse.com/docs/en'), ('github.com/clickhouse/tree/master/docs');
SELECT url, dictGetAll('regexp_dict', ('tag', 'topological_index', 'captured', 'parent'), url, 2) FROM urls;
Response
┌─url────────────────────────────────────┬─dictGetAll('regexp_dict', ('tag', 'topological_index', 'captured', 'parent'), url, 2)─┐
│ clickhouse.com                         │ (['ClickHouse'],[1],[],[])                                                            │
│ clickhouse.com/docs/en                 │ (['ClickHouse Documentation','ClickHouse'],[0,1],['/en'],['ClickHouse'])              │
│ github.com/clickhouse/tree/master/docs │ (['Documentation','GitHub'],[2,3],[NULL],[])                                          │
└────────────────────────────────────────┴───────────────────────────────────────────────────────────────────────────────────────┘

매칭 모드

일부 딕셔너리 설정을 사용하면 패턴 매칭 동작을 변경할 수 있습니다:
  • regexp_dict_flag_case_insensitive: 대소문자를 구분하지 않는 매칭을 사용합니다(기본값: false). 개별 표현식에서는 (?i)(?-i)로 재정의할 수 있습니다.
  • regexp_dict_flag_dotall: .이 줄바꿈 문자와도 매칭되도록 허용합니다(기본값: false).

ClickHouse Cloud에서 정규 표현식 트리 딕셔너리 사용

YAMLRegExpTree 소스는 ClickHouse Open Source에서는 작동하지만 ClickHouse Cloud에서는 작동하지 않습니다. ClickHouse Cloud에서 regexp 트리 딕셔너리를 사용하려면, 먼저 ClickHouse Open Source의 로컬 환경에서 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 테이블을 생성합니다:
CREATE TABLE regexp_dictionary_source_table
(
    id UInt64,
    parent_id UInt64,
    regexp String,
    keys   Array(String),
    values Array(String)
) ENGINE=Memory;
그런 다음 로컬 CSV를 다음과 같이 업데이트합니다
clickhouse client \
    --host MY_HOST \
    --secure \
    --password MY_PASSWORD \
    --query "
    INSERT INTO regexp_dictionary_source_table
    SELECT * FROM input ('id UInt64, parent_id UInt64, regexp String, keys Array(String), values Array(String)')
    FORMAT CSV" < regexp_dict.csv
자세한 내용은 로컬 파일 삽입에서 확인할 수 있습니다. 원본 테이블을 초기화한 후에는 테이블을 소스로 사용해 RegexpTree를 생성할 수 있습니다:
CREATE DICTIONARY regexp_dict
(
    regexp String,
    name String,
    version String
PRIMARY KEY(regexp)
SOURCE(CLICKHOUSE(TABLE 'regexp_dictionary_source_table'))
LIFETIME(0)
LAYOUT(regexp_tree);
마지막 수정일 2026년 6월 10일