CUBE SUGAR CONTAINER

技術系のこと書きます。

Apache Hive の MAP 型を試す

前回に引き続き Apache Hive の複合型の一つ MAP 型を試してみる。

blog.amedama.jp

MAP 型は一般的なプログラミング言語でいうマップや辞書といったデータ構造に相当する。 これを使うとテーブルのカラムに任意のキーで値を格納できる。

環境は次の通り。

$ cat /etc/redhat-release 
CentOS Linux release 7.4.1708 (Core)
$ uname -r
3.10.0-693.5.2.el7.x86_64
$ hadoop version
Hadoop 2.8.3
Subversion https://git-wip-us.apache.org/repos/asf/hadoop.git -r b3fe56402d908019d99af1f1f4fc65cb1d1436a2
Compiled by jdu on 2017-12-05T03:43Z
Compiled with protoc 2.5.0
From source with checksum 9ff4856d824e983fa510d3f843e3f19d
This command was run using /home/vagrant/hadoop-2.8.3/share/hadoop/common/hadoop-common-2.8.3.jar
$ hive --version
Hive 2.3.2
Git git://stakiar-MBP.local/Users/stakiar/Desktop/scratch-space/apache-hive -r 857a9fd8ad725a53bd95c1b2d6612f9b1155f44d
Compiled by stakiar on Thu Nov 9 09:11:39 PST 2017
From source with checksum dc38920061a4eb32c4d15ebd5429ac8a

MAP 型を使ったテーブルを作る

MAP 型を使ってテーブルを作るときは、次のようにキーと値に使う型を指定してカラムを作る。

hive> CREATE TABLE users (
    >   name STRING,
    >   property MAP<STRING, STRING>
    > );
OK
Time taken: 0.047 seconds

ちなみにキーにはプリミティブ型しか指定できない。 試しにキーに ARRAY 型を指定してみると、以下のようにエラーになる。

hive> CREATE TABLE example (
    >   test MAP<ARRAY, STRING>
    > );
...
FAILED: ParseException line 2:11 cannot recognize input near 'ARRAY' ',' 'STRING' in primitive type specification

MAP 型を含むレコードを追加する

他の複合型と同様に、一般的な INSERT INTO ... VALUES を使ったレコードの追加ができない。

hive> INSERT INTO TABLE users
    >   VALUES (MAP("key1", "value1", "key2", "value2"));
FAILED: SemanticException [Error 10293]: Unable to create temp file for insert values Expression of type TOK_FUNCTION not supported in insert/values

代わりに SELECT を使ってデータを作って、それを追加してやる。 MAP() 関数を使うことでキーと値の組を使ったカラムを作れる。

hive> SELECT MAP("key1", "value1", "key2", "value2");
OK
_c0
{"key1":"value1","key2":"value2"}
Time taken: 0.059 seconds, Fetched: 1 row(s)

上記の SELECT で作ったデータを INSERT INTO でテーブルに追加する。

hive> INSERT INTO TABLE users
    >   SELECT "Alice", MAP("key1", "value1", "key2", "value2");
...
OK
_c0 _c1
Time taken: 19.437 seconds

テーブルを確認すると、ちゃんとレコードが入っている。

hive> SELECT * FROM users;
OK
users.name  users.property
Alice   {"key1":"value1","key2":"value2"}
Time taken: 0.136 seconds, Fetched: 1 row(s)

MAP 型の中身を参照する

MAP 型の中身を取り出すときはブラケットの中にキーを指定する。

hive> SELECT name, property["key1"] FROM users;
OK
name    _c1
Alice   value1
Time taken: 0.157 seconds, Fetched: 1 row(s)

存在しないキーの振る舞いを確認する

MAP 型には型さえ合っていれば、これまでに追加したことのないキーであっても大丈夫。

hive> INSERT INTO TABLE users
    >   SELECT "Bob", MAP("key1", "value1", "key3", "value3");
...
OK
_c0 _c1
Time taken: 18.935 seconds

テーブルの内容を確認すると、レコードごとに別々のキーが入っていることが分かる。

hive> SELECT * FROM users;
OK
users.name  users.property
Alice   {"key1":"value1","key2":"value2"}
Bob {"key1":"value1","key3":"value3"}
Time taken: 0.133 seconds, Fetched: 2 row(s)

レコードによってあったりなかったりするキーを参照したときの振る舞いを確認しておこう。

hive> SELECT name,
    >        property["key1"] AS key1,
    >        property["key2"] AS key2,
    >        property["key3"] AS key3
    > FROM users;
OK
name    key1    key2    key3
Alice   value1  value2  NULL
Bob value1  NULL    value3
Time taken: 0.123 seconds, Fetched: 2 row(s)

上記のように、レコードにキーがないときは NULL になるようだ。

次の確認のために、一旦テーブルを削除しておこう。

hive> DROP TABLE users;
OK
Time taken: 0.073 seconds

外部ファイルからデータを読み込む

続いて、外部ファイルからデータを読み込むときの挙動も確認しておく。

外部ファイルから読み込むときは次のように各フィールドやカラムの分割文字を指定しておく。

hive> CREATE TABLE users (
    >   name STRING,
    >   property MAP<STRING, STRING>
    > )
    > ROW FORMAT DELIMITED 
    > FIELDS TERMINATED BY ','  
    > COLLECTION ITEMS TERMINATED BY '$'
    > MAP KEYS TERMINATED BY ':'
    > STORED AS TEXTFILE;
OK
Time taken: 0.075 seconds

次のように CSV ファイルを作っておく。 先のテーブルを定義するときに指定した通り、キーと値は : で区切って、フィールドは $ で分割する。

$ cat << 'EOF' > users.csv
Alice,key1:value1$key2:value2
Bob,key1:value1$key3:value3
EOF

上記を Hive で LOAD DATA を使って読み込む。

hive> LOAD DATA LOCAL INPATH '/home/vagrant/users.csv' INTO TABLE users;
Loading data to table default.users
OK
Time taken: 0.385 seconds

すると、次のようにちゃんとテーブルにデータが格納された。

hive> SELECT * FROM users;
OK
users.name  users.property
Alice   {"key1":"value1","key2":"value2"}
Bob {"key1":"value1","key3":"value3"}
Time taken: 0.13 seconds, Fetched: 2 row(s)

ばっちり。

プログラミング Hive

プログラミング Hive

  • 作者: Edward Capriolo,Dean Wampler,Jason Rutherglen,佐藤直生,嶋内翔,Sky株式会社玉川竜司
  • 出版社/メーカー: オライリージャパン
  • 発売日: 2013/06/15
  • メディア: 大型本
  • この商品を含むブログ (3件) を見る