この章では、Oracle XQuery for Hadoopで提供される、XML Extensions for Apache Hiveの使用方法について説明します。この章の内容は次のとおりです。
XML Extensions for Hiveでは、次のことを可能にするXML処理サポートが提供されています。
HDFSの大規模なXMLファイルのHive表としての問合せ
Hive表のXML文字列の問合せ
Hadoop分散キャッシュのXMLファイル・リソースの問合せ
高負荷DOM解析を使用せずにXMLからアトミック値を効率的に抽出
複雑なXML要素の取得、生成および変換
単一XML値からの表の複数行の生成
XMLでの欠落およびダーティ・データの管理
XML拡張では、次の各W3C最新標準もサポートされています。
XQuery 1.0
XQuery Update Facility 1.0 (変換式)
XPath 2.0
XML Schema 1.0
XML Namespaces
XML拡張には2つのコンポーネントがあります。
XML表を作成するためのXML InputFormatおよびSerDe
「XML表の作成」を参照してください。
XML関数ライブラリ
「Hive関数について」を参照してください。
Oracle XQuery for Hadoop拡張を有効にするには、Hiveの起動時に--auxpath
および-i
引数を使用します。
$ hive --auxpath $OXH_HOME/hive/lib -i $OXH_HOME/hive/init.sql
注意: --auxpath 引数はHIVE_AUX_JARS_PATH の値を設定します。HIVE_AUX_JARS_PATH の値は単一のディレクトリまたはJARファイルのカンマ区切りリストのいずれかになります。Hive構成によってデフォルトでJARのリストにHIVE_AUX_JARS_PATH の値が設定されている場合、$OXH_HOME/hive/lib にあるJARを個々にリストに追加する必要があります。つまり、リストにディレクトリを含めることはできません。ただし、Oracle BigDataLite VMでは、HIVE_AUX_JARS_PATH はHive拡張をデフォルトで含み、そのため--auxpath を指定する必要はありません。 |
拡張を初めて使用するとき、それらがアクセス可能であることを確認します。次の手順では、SRC
という表を作成し、その表に1行ロードした後、xml_query
関数を呼び出します。
拡張がアクセス可能であることを確認するには、次の手順を実行します。
作業しようとしているHadoopクラスタにあるサーバーにログインします。
1行を含むsrc.txt
というテキスト・ファイルを作成します。
$ echo "XXX" > src.txt
Hiveコマンドライン・インタフェース(CLI)を起動します。
$ hive --auxpath $OXH_HOME/hive/lib -i $OXH_HOME/hive/init.sql
init.sql
ファイルには、XML関数を宣言するCREATE TEMPORARY FUNCTION
文が含まれています。
簡単な表を作成します。
hive> CREATE TABLE src(dummy STRING);
SRC
表は、SELECT
構文の要件を満たすためにのみ必要です。これは、SQL関数をテストするためにSELECT
文で参照される、Oracle DatabaseのDUAL
表と同等です。
src.txt
から表にデータをロードします。
hive> LOAD DATA LOCAL INPATH 'src.txt' OVERWRITE INTO TABLE src;
HiveのSELECT
文を使用して表を問い合せます。
hive> SELECT * FROM src; OK xxx
Hive用のOracle XQuery for Hadoop関数を呼び出します。この例では、xml_query
関数を呼び出してXML文字列を解析します。
hive> SELECT xml_query("x/y", "<x><y>123</y><z>456</z></x>") FROM src;
.
.
.
["123"]
拡張がアクセス可能な場合は、例に示すように、問合せで["123"]
が返されます。
Oracle XQuery for Hadoopの拡張を使用すると、Hadoop分散キャッシュのHive表およびXMLファイル・リソース内のXML文字列を問い合せることができます。これらは次の関数です。
xml_query
: 問合せの結果をSTRING
値の配列として返します。
xml_query_as_primitive
: 問合せの結果をHiveプリミティブ値として返します。各Hiveプリミティブ・データ型には、それに対応する名前の個別の関数があります。
xml_exists
: 問合せの結果が空かどうかをテストします。
xml_table
: XML値をゼロ以上の表の行にマップします。この関数を使用すると、XMLのネストされた繰返し要素をHive表の行にマップできます。
「Hive用のOracle XML関数のリファレンス」を参照してください。
この項では、HiveのCREATE TABLE
文を使用して大規模なXMLドキュメントに関する表を作成する方法を説明します。
XML表に関するHive問合せは、MapReduceフレームワークでXMLを並列で処理できるようにOracle XQuery for HadoopによってXMLが分割されるため、適切な規模で行われます。
スケーラブルな処理をサポートし、MapReduceフレームワークで動作するために、表アダプタによって、表の行の作成に使用する要素がスキャンされます。表の一部であると識別した要素のみが解析され、残りのXMLは無視されます。したがって、XML表アダプタでは、入力XMLに制限が課される、XMLドキュメント全体の真の意味での解析は実行されません。これらの制限のため、「XQuery変換の要件」にリストされている制約を満たすXMLドキュメントに関してのみ表を作成できます。それ以外の場合は、エラーが発生するか、誤った結果となる場合があります。
次に、XMLファイルに関するHive表を作成するためのHiveのCREATE TABLE
文の基本構文を示します。
CREATE TABLE table_name (columns) ROW FORMAT SERDE 'oracle.hadoop.xquery.hive.OXMLSerDe' STORED AS INPUTFORMAT 'oracle.hadoop.xquery.hive.OXMLInputFormat' OUTPUTFORMAT 'oracle.hadoop.xquery.hive.OXMLOutputFormat' TBLPROPERTIES(configuration)
パラメータ
XML表の列タイプはすべて、「データ型変換」で示されているHiveプリミティブ・タイプの1つである必要があります。
「CREATE TABLE構成プロパティ」で説明されているいずれかのプロパティ。複数のプロパティはカンマで区切ります。
注意: XML表へのデータの挿入はサポートされていません。 |
次の構成プロパティは、CREATE TABLEコマンドの
configurationパラメータで使用します。
XML解析の表定義にある式のデフォルト・ネームスペースを設定します。値はURIです。
この例ではデフォルトのネームスペースを定義します。
"oxh-default-namespace" = "http://example.com/foo"
XMLファイルの文字エンコードを指定します。サポートされているエンコードは、UTF-8 (デフォルト)、ISO-8859-1およびUS-ASCIIです。
表に対するXMLファイルはすべて、同じ文字エンコードを共有する必要があります。XMLファイルでのエンコード宣言は無視されます。
この例では、文字セットを定義します。
"oxh-charset" = "ISO-8859-1"
oxh-elements
プロパティで選択した要素を行の列にマップする方法を指定します。このプロパティ名では、nameを表の列の名前に置き換えます。値には任意のXQuery式を指定できます。式の初期コンテキスト項目("."変数)は、選択した要素にバインドされます。
問合せが正常に実行された場合でもログ・ファイルを確認してください。列式で値が返されない場合、または動的エラーが発生した場合、列値はNULL
です。エラーが初めて発生したときは、エラーがログに記録され、問合せ処理は続行します。同じ列式で発生した後続のエラーはログに記録されません。
対応するoxh-column
プロパティがない表の列は、次のプロパティが指定されている場合と同様に動作します。
"oxh-column.name" = "(./name | ./@name)[1]"
したがって、デフォルトの動作では、表の列名と一致する最初の子要素または属性が選択されます。「構文の例」を参照してください。
表の行にマップするXMLの要素の名前をカンマ区切りリストで示します。このプロパティは1回指定する必要があります。必須。
次の例では、XMLのfoo
という各要素をHive表の単一の行にマップします。
"oxh-elements" = "foo"
次の例では、XMLのfoo
またはbar
という各要素をHive表の行にマップします。
"oxh-elements" = "foo, bar"
エンティティ参照定義のセットを定義します。
次の例では、XMLのエンティティ参照が、&foo;
から"foo value"および&bar;
から"bar value"に拡張されます。
"oxh-entity.foo" = "foo value" "oxh-entity.bar" = "bar value"
ネームスペース・バインディングを定義します。
次の例では、接頭辞myns
をネームスペースhttp://example.org
にバインドします。
"oxh-namespace.myns" = "http://example.org"
このプロパティを複数回使用して、追加のネームスペースを定義できます。ネームスペース定義は、XMLの解析時に使用されます。oxh-element
およびoxh-column
プロパティの値でそれらを参照することもできます。
次の例では、http://example.org
ネームスペースのfoo
要素のみが表の行にマップされます。
"oxh-namespace.myns" = "http://example.org", "oxh-elements" = "myns:foo", "oxh-column.bar" = "./myns:bar"
この項で示す例は次のとおりです。
この例では、XML要素を列名にマップする方法を示します。
次の表定義で、oxh-elements
プロパティは、XMLのfoo
という各要素が表の単一の行にマップされることを指定しています。oxh-column
プロパティは、BAR
というHive表の列では、STRING
に変換されたbar
という子要素の値を取得し、ZIP
という列では、INT
に変換されたzip
という子要素の値を取得することを指定しています。
CREATE TABLE example (bar STRING, zip INT) ROW FORMAT SERDE 'oracle.hadoop.xquery.hive.OXMLSerDe' STORED AS INPUTFORMAT 'oracle.hadoop.xquery.hive.OXMLInputFormat' OUTPUTFORMAT 'oracle.hadoop.xquery.hive.OXMLOutputFormat' TBLPROPERTIES( "oxh-elements" = "foo", "oxh-column.bar" = "./bar", "oxh-column.zip" = "./zip" )
次のZIP
列の変更された定義で、列は、foo
要素に子のzip
要素がない場合、またはzip
要素に数値以外の値が含まれている場合は、-1の値を受け取ります。
"oxh-column.zip" = " if (./zip castable as xs:int) then xs:int(./zip) else -1 "
次の2つの表定義は同等です。表定義2は、BAR
列とZIP
列のデフォルトのマッピングに基づいています。
表定義1
CREATE TABLE example (bar STRING, zip INT) ROW FORMAT SERDE 'oracle.hadoop.xquery.hive.OXMLSerDe' STORED AS INPUTFORMAT 'oracle.hadoop.xquery.hive.OXMLInputFormat' OUTPUTFORMAT 'oracle.hadoop.xquery.hive.OXMLOutputFormat' TBLPROPERTIES( "oxh-elements" = "foo", "oxh-column.bar" = "(./bar | ./@bar)[1]", "oxh-column.zip" = "(./zip | ./@zip)[1]" )
表定義2
CREATE TABLE example (bar STRING, zip INT) ROW FORMAT SERDE 'oracle.hadoop.xquery.hive.OXMLSerDe' STORED AS INPUTFORMAT 'oracle.hadoop.xquery.hive.OXMLInputFormat' OUTPUTFORMAT 'oracle.hadoop.xquery.hive.OXMLOutputFormat' TBLPROPERTIES( "oxh-elements" = "foo" )
これらの例は、架空のWebサイトのユーザーが送信したコメントを含む小規模なXMLドキュメントに関するHive表を作成する方法を示しています。ドキュメントの各comment
要素には、ユーザーがそのコメントを気に入ったことを示す1つ以上のlike
要素があります。
<comments> <comment id="12345" user="john" text="It is raining :( "/> <comment id="56789" user="kelly" text="I won the lottery!"> <like user="john"/> <like user="mike"/> </comment> <comment id="54321" user="mike" text="Happy New Year!"> <like user="laura"/> </comment> </comments>
CREATE TABLE
の例では、comments.xml
入力ファイルは、ローカル・ファイル・システムの現在の作業ディレクトリにあります。
次のHiveのCREATE TABLE
コマンドでは、COMMENTS
というの表を作成します。ユーザー名、テキストおよびlikeの数が含まれる行が各コメントに対して1行あります。
hive> CREATE TABLE comments (usr STRING, content STRING, likeCt INT) ROW FORMAT SERDE 'oracle.hadoop.xquery.hive.OXMLSerDe' STORED AS INPUTFORMAT 'oracle.hadoop.xquery.hive.OXMLInputFormat' OUTPUTFORMAT 'oracle.hadoop.xquery.hive.OXMLOutputFormat' TBLPROPERTIES( "oxh-elements" = "comment", "oxh-column.usr" = "./@user", "oxh-column.content" = "./@text", "oxh-column.likeCt" = "fn:count(./like)" );
HiveのLOAD DATA
コマンドで、comments.xml
をCOMMENTS
表にロードします。ファイルの内容は、「簡単な例」を参照してください。
hive> LOAD DATA LOCAL INPATH 'comments.xml' OVERWRITE INTO TABLE comments; ]
次の問合せは、COMMENTS
表の内容を示します。
hive> SELECT usr, content, likeCt FROM comments;
.
.
.
john It is raining :( 0
kelly I won the lottery! 2
mike Happy New Year! 1
このCREATE TABLE
コマンドは例1と似ていますが、like
要素がSTRING
列にXMLとして生成される点が異なります。
hive> CREATE TABLE comments2 (usr STRING, content STRING, likes STRING) ROW FORMAT SERDE 'oracle.hadoop.xquery.hive.OXMLSerDe' STORED AS INPUTFORMAT 'oracle.hadoop.xquery.hive.OXMLInputFormat' OUTPUTFORMAT 'oracle.hadoop.xquery.hive.OXMLOutputFormat' TBLPROPERTIES( "oxh-elements" = "comment", "oxh-column.usr" = "./@user", "oxh-column.content" = "./@text", "oxh-column.likes" = "fn:serialize(<likes>{./like}</likes>)" );
HiveのLOAD DATA
コマンドで、comments.xml
を表にロードします。ファイルの内容は、「簡単な例」を参照してください。
hive> LOAD DATA LOCAL INPATH 'comments.xml' OVERWRITE INTO TABLE comments2;
次の問合せは、COMMENTS2
表の内容を示します。
hive> SELECT usr, content, likes FROM comments2;
.
.
.
john It is raining :( <likes/>
kelly I won the lottery! <likes><like user="john"/><like user="mike"/></likes>
mike Happy New Year! <likes><like user="laura"/></likes>
次の問合せでは、like
要素からユーザー名を抽出します。
hive> SELECT usr, t.user FROM comments2 LATERAL VIEW > xml_table("likes/like", comments2.likes, struct("./@user")) t AS user; . . . kelly john kelly mike mike laura
このコマンドでは、各コメントに対する行を含むCOMMENTS3
という表を作成し、単一のSTRING
列にXMLを生成します。
hive> CREATE TABLE comments3 (xml STRING) ROW FORMAT SERDE 'oracle.hadoop.xquery.hive.OXMLSerDe' STORED AS INPUTFORMAT 'oracle.hadoop.xquery.hive.OXMLInputFormat' OUTPUTFORMAT 'oracle.hadoop.xquery.hive.OXMLOutputFormat' TBLPROPERTIES( "oxh-elements" = "comment", "oxh-column.xml" = "fn:serialize(.)" );
HiveのLOAD DATA
コマンドで、comments.xml
を表にロードします。ファイルの内容は、「簡単な例」を参照してください。
hive> LOAD DATA LOCAL INPATH 'comments.xml' OVERWRITE INTO TABLE comments3;
次の問合せは、XML列の内容を示します。
hive> SELECT xml FROM comments3;
.
.
.
<comment id="12345" user="john" text="It is raining :( "/>
<comment id="56789" user="kelly" text="I won the lottery!">
<like user="john"/>
<like user="mike"/>
</comment>
<comment id="54321" user="mike" text="Happy New Year!">
<like user="laura"/>
</comment>
次の問合せでは、IDを抽出してそれらを整数に変換します。
hive> SELECT xml_query_as_int("comment/@id", xml) FROM comments3;
.
.
.
12345
56789
54321
次の各例では、全世界の無料の地図データを提供するOpenStreetMapからのデータを使用します。特定の地理的リージョンまたは地球全体のデータをXMLとしてエクスポートできます。OpenStreetMap XMLドキュメントには主に、一連のnode
、way
およびrelation
要素が含まれています。
次の各例では、OpenStreetMap XMLファイルが/user/name/osm
HDFSディレクトリに格納されます。
関連項目:
|
この例では、次のように各node
要素に対する1行を含む、OpenStreetMap XMLに関する表を作成します。
node
要素のid
、lat
、lon
およびuser
属性は、表の列にマップされます。
年がtimestamp
属性から抽出され、YEAR
列にマップされます。ノードにtimestamp
属性がない場合、年には-1
が使用されます。
node
要素に子のtag
要素がある場合は、TAGS
列にXML文字列として格納されます。node
に子のtag
要素がない場合、列値はNULL
です。
hive> CREATE EXTERNAL TABLE nodes ( id BIGINT, latitude DOUBLE, longitude DOUBLE, year SMALLINT, tags STRING ) ROW FORMAT SERDE 'oracle.hadoop.xquery.hive.OXMLSerDe' STORED AS INPUTFORMAT 'oracle.hadoop.xquery.hive.OXMLInputFormat' OUTPUTFORMAT 'oracle.hadoop.xquery.hive.OXMLOutputFormat' LOCATION '/user/name/osm' TBLPROPERTIES ( "oxh-elements" = "node", "oxh-column.id" = "./@id", "oxh-column.latitude" = "./@lat", "oxh-column.longitude" = "./@lon", "oxh-column.year" = " if (fn:exists(./@timestamp)) then fn:year-from-dateTime(xs:dateTime(./@timestamp)) else -1 ", "oxh-column.tags" = " if (fn:exists(./tag)) then fn:serialize(<tags>{./tag}</tags>) else () " );
次の問合せは、年ごとのノード数を返します。
hive> SELECT year, count(*) FROM nodes GROUP BY year;
次の問合せは、ノード全体の合計タグ数を返します。
hive> SELECT sum(xml_query_as_int("count(tags/tag)", tags)) FROM nodes;
OpenStreetMap XMLでは、node
、way
およびrelation
要素で、データに関与したユーザーなどの共通属性のセットが共有されます。次の表では、各node
、way
およびrelation
要素に対して1行生成します。
hive> CREATE EXTERNAL TABLE osm ( id BIGINT, uid BIGINT, type STRING ) ROW FORMAT SERDE 'oracle.hadoop.xquery.hive.OXMLSerDe' STORED AS INPUTFORMAT 'oracle.hadoop.xquery.hive.OXMLInputFormat' OUTPUTFORMAT 'oracle.hadoop.xquery.hive.OXMLOutputFormat' LOCATION '/user/name/osm' TBLPROPERTIES ( "oxh-elements" = "node, way, relation", "oxh-column.id" = "./@id", "oxh-column.uid" = "./@uid", "oxh-column.type" = "./name()" );
次の問合せは、node
、way
およびrelation
要素の数を返します。TYPE
列は、選択した要素の名前であるnode
、way
またはrelation
のいずれかに設定されます。
hive> SELECT type, count(*) FROM osm GROUP BY type;
次の問合せは、個別のユーザーIDの数を返します。
hive> SELECT count(*) FROM (SELECT uid FROM osm GROUP BY uid) t;