メインコンテンツまでスキップ
メインコンテンツまでスキップ

辞書操作用の関数

注記

DDLクエリで作成された辞書の場合、dict_nameパラメータは完全に指定する必要があります。例えば、<database>.<dict_name>の形式です。そうでない場合、現在のデータベースが使用されます。

辞書の接続と設定に関する情報は、辞書を参照してください。

dictGet, dictGetOrDefault, dictGetOrNull

辞書から値を取得します。

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 — 辞書のカラム名、文字列リテラルまたはカラム名のタプル、タプル(文字列リテラル
  • id_expr — キーの値。として辞書のキータイプ値または辞書の設定に応じたタプルタイプの値を返す。
  • default_value_expr — 辞書にid_exprキーを持つ行がない場合に返される値。またはタプル()で、attr_names属性に設定されたデータタイプで値を返す。

返される値

  • ClickHouseが属性を属性のデータタイプとして正常に解析できた場合、関数はid_exprに対応する辞書属性の値を返します。

  • 辞書にid_exprに対応するキーがない場合は次の通りです。

    • dictGetは、辞書設定で属性に指定された<null_value>要素の内容を返します。
    • dictGetOrDefaultは、default_value_exprパラメータとして渡された値を返します。
    • dictGetOrNullは、辞書でキーが見つからなかった場合にはNULLを返します。

ClickHouseは属性の値を解析できない場合や、値が属性のデータタイプと一致しない場合には例外をスローします。

単純キー辞書の例

次の内容を持つテキストファイル ext-dict-test.csv を作成します。

1,1
2,2

最初のカラムが id 、2番目のカラムが 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 、2番目が c1 、3番目が 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

キーが辞書に存在するかどうかを確認します。

dictHas('dict_name', id_expr)

引数

  • dict_name — 辞書の名前。文字列リテラル
  • id_expr — キーの値。として辞書のキータイプ値または辞書の設定に応じたタプルタイプの値を返します。

返される値

  • キーがない場合は0。UInt8
  • キーがある場合は1。UInt8

dictGetHierarchy

キーのすべての親を含む配列を作成します。階層辞書

構文

dictGetHierarchy('dict_name', key)

引数

返される値

dictIsIn

辞書の階層チェーン全体を通じてキーの先祖を確認します。

dictIsIn('dict_name', child_id_expr, ancestor_id_expr)

引数

  • dict_name — 辞書の名前。文字列リテラル
  • child_id_expr — チェックするキー。としてUInt64型の値を返します。
  • ancestor_id_exprchild_id_exprキーの仮想的な先祖。としてUInt64型の値を返します。

返される値

  • child_id_exprancestor_id_exprの子でない場合は0。UInt8
  • child_id_exprancestor_id_exprの子であるか、child_id_exprancestor_id_exprである場合は1。UInt8

dictGetChildren

最初のレベルの子供をインデックスの配列として返します。それはdictGetHierarchy関数の逆変換です。

構文

dictGetChildren(dict_name, key)

引数

返される値

  • キーの最初のレベルの子孫。Array(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]                                                  │
│ []                                                   │
└──────────────────────────────────────────────────────┘

dictGetDescendant

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]                                                        │
│ []                                                         │
└────────────────────────────────────────────────────────────┘

dictGetAll

正規表現木辞書に一致する各キーのノードのすべての属性値を取得します。

各値をArray(T)として返すことを除いて、この関数はdictGetと同様に動作します。

構文

dictGetAll('dict_name', attr_names, id_expr[, limit])

引数

  • dict_name — 辞書の名前。文字列リテラル
  • attr_names — 辞書のカラム名、文字列リテラルまたはカラム名のタプル、タプル(文字列リテラル)。
  • id_expr — キーの値。として辞書のキータイプ値の配列または辞書の設定に応じたタプル-タイプの値を返す。
  • limit - 返される各値配列の最大長さ。切り捨てる際には、子ノードが親ノードより優先され、それ以外の場合は正規表現木辞書の定義されたリスト順序が尊重されます。指定されていない場合、配列の長さは無制限です。

返される値

  • ClickHouseが辞書内で属性を正常に解析した場合、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, dictGetInt64
  • dictGetUInt8, dictGetUInt16, dictGetUInt32, dictGetUInt64
  • dictGetFloat32, dictGetFloat64
  • dictGetDate
  • dictGetDateTime
  • dictGetUUID
  • dictGetString
  • dictGetIPv4, 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またはタプルタイプの値を返します。
  • default_value_expr — 辞書にid_exprキーを持つ行がない場合に返される値。で、attr_name属性に設定されたデータタイプで値を返します。

返される値

  • ClickHouseが属性のデータタイプとして属性を正常に解析できた場合、関数はid_exprに対応する辞書属性の値を返します。

  • 辞書に要求されたid_exprがない場合は:

    • dictGet[Type]は、辞書設定で属性に指定された<null_value>要素の内容を返します。
    • dictGet[Type]OrDefaultは、default_value_exprパラメータとして渡された値を返します。

ClickHouseは属性の値を解析できない場合や、値が属性のデータタイプと一致しない場合には例外をスローします。