对于通过 DDL 查询创建的字典,必须完整指定 dict_name 参数,格式为 <database>.<dict_name>。否则,将使用当前数据库。
从字典中检索值。
dictGet('dict_name', attr_names, id_expr) dictGetOrDefault('dict_name', attr_names, id_expr, default_value_expr) dictGetOrNull('dict_name', attr_name, id_expr)
参数
dict_name — 字典的名称。字符串常量。attr_names — 字典的列名,字符串常量,或列名的元组,Tuple(字符串常量)。id_expr — 键值。根据字典配置,返回字典键类型值或 Tuple 类型值的表达式。default_value_expr — 如果字典中不包含具有 id_expr 键的行则返回的值。表达式 或 Tuple(表达式),返回值的数据类型需与 attr_names 属性配置的类型一致。返回的值
id_expr 对应的字典属性值。id_expr 对应的键,则:
dictGet 返回在字典配置中为该属性指定的 <null_value> 元素内容。dictGetOrDefault 返回 default_value_expr 参数传递的值。dictGetOrNull 在未找到键的情况下返回 NULL。如果 ClickHouse 无法解析属性的值或值与属性数据类型不匹配,它将报错。
简单键字典示例
创建一个文本文件 ext-dict-test.csv,内容如下:
1,12,2
第一列为 id,第二列为 c1。
配置字典:
<clickhouse> <dictionary> <name>ext-dict-test</name> <source> <file> <path>/path-to/ext-dict-test.csv</path> <format>CSV</format> </file> </source> <layout> <flat /> </layout> <structure> <id> <name>id</name> </id> <attribute> <name>c1</name> <type>UInt32</type> <null_value></null_value> </attribute> </structure> <lifetime>0</lifetime> </dictionary> </clickhouse>
执行查询:
SELECT dictGetOrDefault('ext-dict-test', 'c1', number + 1, toUInt32(number * 10)) AS val, toTypeName(val) AS type FROM system.numbers LIMIT 3;
┌─val─┬─type───┐ │ 1 │ UInt32 │ │ 2 │ UInt32 │ │ 20 │ UInt32 │ └───┴───────┘
复杂键字典示例
创建一个文本文件 ext-dict-mult.csv,内容如下:
1,1,'1' 2,2,'2' 3,3,'3'
第一列为 id,第二列为 c1,第三列为 c2。
配置字典:
<clickhouse> <dictionary> <name>ext-dict-mult</name> <source> <file> <path>/path-to/ext-dict-mult.csv</path> <format>CSV</format> </file> </source> <layout> <flat /> </layout> <structure> <id> <name>id</name> </id> <attribute> <name>c1</name> <type>UInt32</type> <null_value></null_value> </attribute> <attribute> <name>c2</name> <type>String</type> <null_value></null_value> </attribute> </structure> <lifetime>0</lifetime> </dictionary> </clickhouse>
执行查询:
SELECT dictGet('ext-dict-mult', ('c1','c2'), number + 1) AS val, toTypeName(val) AS type FROM system.numbers LIMIT 3;
┌─val─────┬─type───────────┐ │ (1,'1') │ Tuple(UInt8, String) │ │ (2,'2') │ Tuple(UInt8, String) │ │ (3,'3') │ Tuple(UInt8, String) │ └────────┴──────────────┘
范围键字典示例
输入表:
CREATE TABLE range_key_dictionary_source_table ( key UInt64, start_date Date, end_date Date, value String, value_nullable Nullable(String) ) ENGINE = TinyLog(); INSERT INTO range_key_dictionary_source_table VALUES(1, toDate('2019-05-20'), toDate('2019-05-20'), 'First', 'First'); INSERT INTO range_key_dictionary_source_table VALUES(2, toDate('2019-05-20'), toDate('2019-05-20'), 'Second', NULL); INSERT INTO range_key_dictionary_source_table VALUES(3, toDate('2019-05-20'), toDate('2019-05-20'), 'Third', 'Third');
创建字典:
CREATE DICTIONARY range_key_dictionary ( key UInt64, start_date Date, end_date Date, value String, value_nullable Nullable(String) ) PRIMARY KEY key SOURCE(CLICKHOUSE(HOST 'localhost' PORT tcpPort() TABLE 'range_key_dictionary_source_table')) LIFETIME(MIN 1 MAX 1000) LAYOUT(RANGE_HASHED()) RANGE(MIN start_date MAX end_date);
执行查询:
SELECT (number, toDate('2019-05-20')), dictHas('range_key_dictionary', number, toDate('2019-05-20')), dictGetOrNull('range_key_dictionary', 'value', number, toDate('2019-05-20')), dictGetOrNull('range_key_dictionary', 'value_nullable', number, toDate('2019-05-20')), dictGetOrNull('range_key_dictionary', ('value', 'value_nullable'), number, toDate('2019-05-20')) FROM system.numbers LIMIT 5 FORMAT TabSeparated;
结果:
(0,'2019-05-20') 0 \N \N (NULL,NULL) (1,'2019-05-20') 1 First First ('First','First') (2,'2019-05-20') 1 Second \N ('Second',NULL) (3,'2019-05-20') 1 Third Third ('Third','Third') (4,'2019-05-20') 0 \N \N (NULL,NULL)
更多内容请参见:
检查字典中是否存在某个键。
dictHas('dict_name', id_expr)
参数
dict_name — 字典的名称。字符串常量。id_expr — 键值。根据字典配置,返回字典键类型值或 Tuple 类型值的表达式。返回的值
创建一个数组,包含在分层字典中某个键的所有父项。
语法
dictGetHierarchy('dict_name', key)
参数
dict_name — 字典的名称。字符串常量。key — 键值。返回一个 UInt64 类型值的表达式。返回的值
通过字典中的整个层级链检查某个键的祖先键。
dictIsIn('dict_name', child_id_expr, ancestor_id_expr)
参数
dict_name — 字典的名称。字符串常量。child_id_expr — 要检查的键。返回 UInt64 类型值的表达式。ancestor_id_expr — 待验证的 child_id_expr 的祖先键。返回一个 UInt64 类型值的表达式。返回的值
child_id_expr 不是 ancestor_id_expr 的子项。UInt8 类型。child_id_expr 是 ancestor_id_expr 的子项,或者如果 child_id_expr 是 ancestor_id_expr。UInt8 类型。返回第一级子节点的索引数组。与dictGetHierarchy互为逆操作。
语法
dictGetChildren(dict_name, key)
参数
dict_name — 字典的名称。字符串常量。key — 键值。返回一个 UInt64 类型值的表达式。返回值
示例
考虑分层字典:
┌─id─┬─parent_id─┐ │ 1 │ 0 │ │ 2 │ 1 │ │ 3 │ 1 │ │ 4 │ 2 │ └───┴───────┘
第一层子节点:
SELECT dictGetChildren('hierarchy_flat_dictionary', number) FROM system.numbers LIMIT 4;
┌─dictGetChildren('hierarchy_flat_dictionary', number)─┐ │ [1] │ │ [2,3] │ │ [4] │ │ [] │ └─────────────────────────────────┘
返回所有后代节点,效果等同于将dictGetChildren函数递归应用 level 次。
语法
dictGetDescendants(dict_name, key, level)
参数
dict_name — 字典的名称。字符串常量。key — 键值。返回一个 UInt64 类型值的表达式。level — 层级深度。若 level = 0,则返回所有层级的后代节点直至最底层。UInt8 类型。返回值
示例
考虑层级字典:
┌─id─┬─parent_id─┐ │ 1 │ 0 │ │ 2 │ 1 │ │ 3 │ 1 │ │ 4 │ 2 │ └───┴───────┘
查询所有后代节点:
SELECT dictGetDescendants('hierarchy_flat_dictionary', number) FROM system.numbers LIMIT 4;
┌─dictGetDescendants('hierarchy_flat_dictionary', number)─┐ │ [1,2,3,4] │ │ [2,3,4] │ │ [4] │ │ [] │ └───────────────────────────────────┘
第一层后代节点:
SELECT dictGetDescendants('hierarchy_flat_dictionary', number, 1) FROM system.numbers LIMIT 4;
┌─dictGetDescendants('hierarchy_flat_dictionary', number, 1)─┐ │ [1] │ │ [2,3] │ │ [4] │ │ [] │ └─────────────────────────────────────┘
检索与正则表达式树字典(regular expression tree dictionary)中每个键匹配的节点的所有属性值。
除了返回 Array(T) 类型而非 T 外,此函数的行为与 dictGet 类似。
语法
dictGetAll('dict_name', attr_names, id_expr[, limit])
参数
dict_name — 字典的名称。字符串常量。attr_names — 字典的列名,字符串常量,或列名的元组,Tuple(字符串常量)。id_expr — 键值。返回字典键类型值数组或 Tuple 类型值的表达式(根据字典配置)。limit - 返回的每个值数组的最大长度。截断时,子节点优先于父节点,除此之外正则表达式树字典的定义列表顺序得到尊重。如果未指定,数组长度不受限制。返回的值
id_expr 对应的字典属性值数组。id_expr 对应的键,则返回空数组。如果 ClickHouse 无法解析属性的值或值与属性数据类型不匹配,它将报错。
示例
假设以下正则表达式树字典:
CREATE DICTIONARY regexp_dict ( regexp String, tag String ) PRIMARY KEY(regexp) SOURCE(YAMLRegExpTree(PATH '/var/lib/clickhouse/user_files/regexp_tree.yaml')) LAYOUT(regexp_tree) ...
# /var/lib/clickhouse/user_files/regexp_tree.yaml - regexp: 'foo' tag: 'foo_attr' - regexp: 'bar' tag: 'bar_attr' - regexp: 'baz' tag: 'baz_attr'
获取所有匹配值:
SELECT dictGetAll('regexp_dict', 'tag', 'foobarbaz');
┌─dictGetAll('regexp_dict', 'tag', 'foobarbaz')─┐ │ ['foo_attr','bar_attr','baz_attr'] │ └─────────────────────────────┘
获取最多 2 个匹配值:
SELECT dictGetAll('regexp_dict', 'tag', 'foobarbaz', 2);
┌─dictGetAll('regexp_dict', 'tag', 'foobarbaz', 2)─┐ │ ['foo_attr','bar_attr'] │ └───────────────────────────────┘
ClickHouse 支持专门的函数,无论字典配置如何,都将字典属性值转换为特定数据类型。
函数包括:
dictGetInt8, dictGetInt16, dictGetInt32, dictGetInt64dictGetUInt8, dictGetUInt16, dictGetUInt32, dictGetUInt64dictGetFloat32, dictGetFloat64dictGetDatedictGetDateTimedictGetUUIDdictGetStringdictGetIPv4, dictGetIPv6所有这些函数都有 OrDefault 修改。例如,dictGetDateOrDefault。
语法:
dictGet[Type]('dict_name', 'attr_name', id_expr) dictGet[Type]OrDefault('dict_name', 'attr_name', id_expr, default_value_expr)
参数
dict_name — 字典的名称。字符串常量。attr_name — 字典的列名。字符串常量。id_expr — 键值。根据字典配置,返回 UInt64 类型值或 Tuple 类型值的表达式。default_value_expr — 如果字典中不包含具有 id_expr 键的行则返回的值。表达式返回值的数据类型需与 attr_name 属性配置的类型一致。返回的值
id_expr 对应的字典属性值。id_expr,那么:
dictGet[Type] 返回在字典配置中为该属性指定的 <null_value> 元素的内容。dictGet[Type]OrDefault 返回作为 default_value_expr 参数传递的值。如果 ClickHouse 无法解析属性的值或值与属性数据类型不匹配,它将报错。