Apache Pigで辞書を当てる方法

bigdata ビッグデータ

あるフィールドに用意したキーワードが含まれるレコードを取得したいことがよくあると思います。
Apache Pig でそれを実現する方法を記事にまとめました。

スポンサーリンク

前提

  • Python で 辞書を読み込んで Pig テンプレートに埋め込みます。

辞書

  • このようにキーワードが羅列されているとします。

keywords.tsv

Hoge
Fuga
Piyo

辞書を当てる方法

手順は以下のようになります。

①辞書を 1 行に変換する
②Pig テンプレートに 1 行変換した辞書を埋め込む

①辞書を 1 行に変換する

  • キーワードを OR で当てるために辞書を読み込み, 1 行に変換します。
keywords_as_one_line = load_dictionary_as_one_line('keywords.tsv', '|')
def load_dictionary_as_one_line(dictionary_file, separator):
    with open(dictionary_file) as f:
        lines_one_str = ''
        # a\nb\nc\n -> a|b|c|d
        lines = f.readlines()
        for line in lines:
            word = line.rstrip(os.linesep)
            if(word != ''):
                lines_one_str += word + separator
        return lines_one_str[:-1]

②Pig テンプレートに 1 行変換した辞書を埋め込む

  • Pig テンプレートに1行に変換した辞書を埋め込みます。
COND = {
    '$KEYWORDS': f'.*({keywords_as_one_line}).*',
}_
translate_pig('extract_text_template.pig', 'extract_text.pig', COND)
def translate_pig(template: str, output: str, d: {str, str}):
    for i, (k, v) in enumerate(d.items()):
        if i == 0:
            substitute_condition(template, output, k, v)
        else:
            substitute_condition(output, output, k, v)
    return 0

変換前 Pig

CANDIDATES = FOREACH Data GENERATE
    (CASE
        WHEN text matches '$KEYWORDS' THEN 1
        ELSE 0
    END)                            AS flag:int;

変換後 Pig

  • この例では text に matches で辞書のキーワードが含まれるか見ます。
CANDIDATES = FOREACH Data GENERATE
    (CASE
        WHEN text matches '.*(Hoge|Fuga|Piyo).*' THEN 1
        ELSE 0
    END)                            AS flag:int;
タイトルとURLをコピーしました