ヘッダーをスキップ
Oracle® Big Data Connectorsユーザーズ・ガイド
リリース2 (2.5)
E53261-01
  目次へ移動
目次
索引へ移動
索引

前
 
次
 

7 Oracle XML Extensions for Hive

この章では、Oracle XQuery for Hadoopを備えたOracle Big Data Applianceで提供される、XML Extensions for Apache Hiveの使用方法について説明します。この章の内容は次のとおりです。


注意:

この章で説明する機能は、Oracle Big Data Applianceでのみ使用できます。これらは、ダウンロード可能なOracle XQuery for Hadoopインストール・パッケージに含まれていません。

7.1 XML Extensions for 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つのコンポーネントがあります。

7.2 Hive拡張の使用

Oracle XQuery for Hadoop拡張を有効にするには、Hiveの起動時に--auxpathおよび-i引数を使用します。

$ hive --auxpath $OXH_HOME/hive/lib -i $OXH_HOME/hive/init.sql

拡張を初めて使用するとき、それらがアクセス可能であることを確認します。次の手順では、SRCという表を作成し、その表に1行ロードした後、xml_query関数を呼び出します。

拡張がアクセス可能であることを確認するには、次の手順を実行します。 

  1. 作業するOracle Big Data Applianceサーバーにログインします。

  2. 1行を含むsrc.txtというテキスト・ファイルを作成します。

    $ echo "XXX" > src.txt
    
  3. Hiveコマンドライン・インタフェース(CLI)を起動します。

    $ hive --auxpath $OXH_HOME/hive/lib -i $OXH_HOME/hive/init.sql
    

    init.sqlファイルには、XML関数を宣言するCREATE TEMPORARY FUNCTION文が含まれています。

  4. 簡単な表を作成します。

    hive> CREATE TABLE src(dummy STRING);
    

    SRC表は、SELECT構文の要件を満たすためにのみ必要です。これは、SQL関数をテストするためにSELECT文で参照される、Oracle DatabaseのDUAL表と同等です。

  5. src.txtから表にデータをロードします。

    hive> LOAD DATA LOCAL INPATH 'src.txt' OVERWRITE INTO TABLE src;
    
  6. HiveのSELECT文を使用して表を問い合せます。

    hive> SELECT * FROM src;
    OK
    xxx
    
  7. 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"]が返されます。

7.3 Hive関数について

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関数のリファレンス」を参照してください。

7.4 XML表の作成

この項では、HiveのCREATE TABLE文を使用して大規模なXMLドキュメントに関する表を作成する方法を説明します。

XML表に関するHive問合せは、MapReduceフレームワークでXMLを並列で処理できるようにOracle XQuery for HadoopによってXMLが分割されるため、適切な規模で行われます。

スケーラブルな処理をサポートし、MapReduceフレームワークで動作するために、表アダプタによって、表の行の作成に使用する要素がスキャンされます。表の一部であると識別した要素のみが解析され、残りのXMLは無視されます。したがって、XML表アダプタでは、入力XMLに制限が課される、XMLドキュメント全体の真の意味での解析は実行されません。これらの制限のため、「XQuery変換の要件」にリストされている制約を満たすXMLドキュメントに関してのみ表を作成できます。それ以外の場合は、エラーが発生するか、誤った結果となる場合があります。

7.4.1 XML表に対するHiveのCREATE TABLE構文

次に、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)

パラメータ 

columns

XML表の列タイプはすべて、「データ型変換」で示されているHiveプリミティブ・タイプの1つである必要があります。

configuration

「CREATE TABLE構成プロパティ」で説明されているいずれかのプロパティ。複数のプロパティはカンマで区切ります。


注意:

XML表へのデータの挿入はサポートされていません。

7.4.2 CREATE TABLE構成プロパティ

次の構成プロパティは、CREATE TABLEコマンドのconfigurationパラメータで使用します。

oxh-elements

表の行にマップするXMLの要素の名前をカンマ区切りリストで示します。このプロパティは1回指定する必要があります。必須。

次の例では、XMLのfooという各要素をHive表の単一の行にマップします。

"oxh-elements" = "foo"

次の例では、XMLのfooまたはbarという各要素をHive表の行にマップします。

"oxh-elements" = "foo, bar"
oxh-column.name

oxh-elementsプロパティで選択した要素を行の列にマップする方法を指定します。このプロパティ名では、nameを表の列の名前に置き換えます。値には任意のXQuery式を指定できます。式の初期コンテキスト項目("."変数)は、選択した要素にバインドされます。

問合せが正常に実行された場合でもログ・ファイルを確認してください。列式で値が返されない場合、または動的エラーが発生した場合、列値はNULLです。エラーが初めて発生したときは、エラーがログに記録され、問合せ処理は続行します。同じ列式で発生した後続のエラーはログに記録されません。

対応するoxh-columnプロパティがない表の列は、次のプロパティが指定されている場合と同様に動作します。

"oxh-column.name" = "(./name | ./@name)[1]"

したがって、デフォルトの動作では、表の列名と一致する最初の子要素または属性が選択されます。「構文の例」を参照してください。

oxh-namespace.prefix

ネームスペース・バインディングを定義します。

次の例では、接頭辞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"
oxh-entity.name

エンティティ参照定義のセットを定義します。

次の例では、XMLのエンティティ参照が、&foo;から"foo value"および&bar;から"bar value"に拡張されます。

"oxh-entity.foo" = "foo value"
"oxh-entity.bar" = "bar value"
oxh-charset

XMLファイルの文字エンコードを指定します。サポートされているエンコードは、UTF-8 (デフォルト)、ISO-8859-1およびUS-ASCIIです。

表に対するXMLファイルはすべて、同じ文字エンコードを共有する必要があります。XMLファイルでのエンコード宣言は無視されます。

この例では、文字セットを定義します。

"oxh-charset" = "ISO-8859-1"

7.4.3 CREATE TABLEの例

この項で示す例は次のとおりです。

7.4.3.1 構文の例

この例では、XML要素を列名にマップする方法を示します。

例1   基本的な列マッピング

次の表定義で、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"
)
例2   条件付き列マッピング

次のZIP列の変更された定義で、列は、foo要素に子のzip要素がない場合、またはzip要素に数値以外の値が含まれている場合は、-1の値を受け取ります。

"oxh-column.zip" = "
   if (./zip castable as xs:int) then 
      xs:int(./zip) 
   else 
      -1
"
例3   デフォルトの列マッピング

次の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"
)

7.4.3.2 簡単な例

これらの例は、架空の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入力ファイルは、ローカル・ファイル・システムの現在の作業ディレクトリにあります。

例1   表の作成

次の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.xmlCOMMENTS表にロードします。ファイルの内容は、「簡単な例」を参照してください。

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
例2   XML列の問合せ

この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
例3   単一の文字列の列におけるXMLの生成

このコマンドでは、各コメントに対する行を含む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

7.4.3.3 OpenStreetMapの例

次の各例では、全世界の無料の地図データを提供するOpenStreetMapからのデータを使用します。特定の地理的リージョンまたは地球全体のデータをXMLとしてエクスポートできます。OpenStreetMap XMLドキュメントには主に、一連のnodewayおよびrelation要素が含まれています。

次の各例では、OpenStreetMap XMLファイルが/user/name/osm HDFSディレクトリに格納されます。


関連項目:


例1   OpenStreetMap XMLに関する表の作成

この例では、次のように各node要素に対する1行を含む、OpenStreetMap XMLに関する表を作成します。

  • node要素のidlatlonおよび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;
例2   

OpenStreetMap XMLでは、nodewayおよびrelation要素で、データに関与したユーザーなどの共通属性のセットが共有されます。次の表では、各nodewayおよびrelation要素に対して1行生成します。


関連項目:

OpenStreetMapの要素および属性の説明は、次のサイトを参照してください。

http://wiki.openstreetmap.org/wiki/Elements


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()"
  );

次の問合せは、nodewayおよびrelation要素の数を返します。TYPE列は、選択した要素の名前であるnodewayまたはrelationのいずれかに設定されます。

hive> SELECT type, count(*) FROM osm GROUP BY type;
 

次の問合せは、個別のユーザーIDの数を返します。

hive> SELECT count(*) FROM (SELECT uid FROM osm GROUP BY uid) t;