この章では、Oracle XQuery for Hadoopを備えたOracle Big Data Applianceで提供される、XML Extensions for Apache Hiveの使用方法について説明します。この章の内容は次のとおりです。
注意: この章で説明する機能は、Oracle Big Data Applianceでのみ使用できます。他のHadoopクラスタでは使用できません。 |
Oracle XQuery for Hadoopでは、次のことを可能にする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関数ライブラリ
「Apache HiveのXML関数ライブラリ」を参照してください。
Oracle XQuery for Hadoop拡張を有効にするには、Hiveの起動時に--auxpath
および-i
引数を使用します。
$ hive --auxpath $OXH_HOME/hive/lib -i $OXH_HOME/hive/init.sql
拡張を初めて使用するとき、それらがアクセス可能であることを確認する場合があります。次の手順では、SRCという表を作成し、その表に1行ロードした後、xml_query関数を呼び出します。
SRC表は、SELECT
構文の要件を満たすためにのみ必要です。これは、SQL関数をテストするためにSELECT
文で参照される、Oracle DatabaseのDUAL
表と同等です。
拡張がアクセス可能であることを確認するには、次の手順を実行します。
作業するOracle Big Data Applianceサーバーにログインします。
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
文が含まれています。
単純な表を作成し、src.txtからデータをロードします。
hive> CREATE TABLE src(dummy STRING); hive> LOAD DATA LOCAL INPATH 'src.txt' OVERWRITE INTO TABLE src;
Hiveに対してOracle XQuery for Hadoop関数を呼び出します。
hive> SELECT xml_query("x/y", "<x><y>123</y><z>456</z></x>") FROM src;
拡張がアクセス可能な場合は、問合せで["123"]
が返されます。
この項では、HiveのCREATE TABLE
文を使用して大規模なXMLドキュメントに関する表を作成する方法を説明します。
XML表に関するHive問合せは、MapReduceフレームワークでXMLを並列で処理できるようにOracle XQuery for HadoopによってXMLが分割されるため、適切な規模で行われます。
スケーラブルな処理をサポートし、MapReduceフレームワークで動作するために、表アダプタによって、表の行の作成に使用する要素がスキャンされます。表の一部であると識別した要素のみが解析され、残りのXMLは無視されます。したがって、XML表アダプタでは、入力XMLに制限が課される、XMLドキュメント全体の真の意味での解析は実行されません。これらの制限のため、「XQuery変換の要件」にリストされている制約を満たすXMLドキュメントに関してのみ表を作成できます。それ以外の場合は、エラーが発生するか、誤った結果となる場合があります。
次は、XMLファイルに関するHive表を作成するときに使用する基本構文です。
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)
columns: XML表の列タイプはすべて、「データ型変換について」で示されているHiveプリミティブ・タイプの1つである必要があります。
configuration: 「CREATE TABLE構成プロパティ」で説明されているいずれかのプロパティ。
注意: XML表への挿入はサポートされていません。 |
CREATE TABLE構成プロパティ
表の行にマップするXMLの要素の名前をカンマ区切りリストで示します。このプロパティは1回指定する必要があります。必須。
次の例では、XMLのfoo
という各要素をHive表の単一の行にマップします。
"oxh-elements" = "foo"
次の例では、XMLのfoo
またはbar
という各要素をHive表の行にマップします。
"oxh-elements" = "foo, bar"
oxh-elements
プロパティで選択した要素を行の列にマップする方法を指定します。このプロパティ名では、nameを表の列の名前に置き換えます。値には任意のXQuery式を指定できます。式の初期コンテキスト項目("."変数)は、選択した要素にバインドされます。
問合せが正常に実行された場合でもログ・ファイルを必ず確認してください。列式で値が返されない場合、または動的エラーが発生した場合、列値はNULL
です。エラーが初めて発生したときは、エラーがログに記録され、問合せ処理は続行します。同じ列式で発生した後続のエラーはログに記録されません。
次の例で、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" = "./bat", "oxh-column.zip" = "./zip" )
次のzip
列の変更された定義で、列は、foo
要素に子のzip
要素がない場合、またはzip
要素に数値以外の値が含まれている場合は、-1の値を受け取ります。
"oxh-column.zip" = " if (./zip castable as xs:int) then xs:int(./zip) else -1 "
対応するoxh-column
プロパティがない表の列は、次のプロパティが指定されている場合と同様に動作します。
"oxh-column.name" = "(./name | ./@name)[1]"
したがって、デフォルトの動作では、表の列名と一致する最初の子要素または属性が選択されます。
次の2つの表定義は同等です。
表定義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" )
ネームスペース・バインディングを定義します。
次の例では、接頭辞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のエンティティ参照が、&foo;
から"foo value"および&bar;
から"bar value"に拡張されます。
"oxh-entity.foo" = "foo value" "oxh-entity.bar" = "bar value"
XMLファイルの文字エンコードを指定します。サポートされているエンコードは、UTF-8 (デフォルト)、ISO-8859-1およびUS-ASCIIです。
次の例では、文字セットを設定します。
"oxh-charset" = "ISO-8859-1"
この項には、単純なデータセットを使用したいくつかの例と、非常に大規模で複雑な実際のデータセットを使用した他の例が含まれています。
これらの例は、架空の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入力ファイルは、ローカル・ファイル・システムの現在の作業ディレクトリにあります。
次の例では、ユーザー、likeの数およびテキストで構成される、各コメントに対する行を含むCOMMENTS
という表を作成します。
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
次の例は例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;