3 Big Data Spatial and GraphとOracle Databaseとの統合
Oracle Big Data Connectorsを使用して、Big Data Spatial and GraphとOracle Databaseとの間の空間データ・アクセスを簡略化できます。
この章では、次に関する知識があることを前提としています。
-
Oracle SQL Connector for HDFS
詳細は、「Oracle SQL Connector for Hadoop Distributed File System」を参照してください。
-
Oracle Loader for Hadoop
詳細は、「Oracle Loader for Hadoop」を参照してください
-
Apache Hive
詳細は、Apache Hiveのドキュメント(https://cwiki.apache.org/confluence/display/Hive/Home#Home-UserDocumentation)を参照してください。
- 区切りテキスト・ファイルを使用したOracle SQL Connector for HDFSの使用
このトピックは、HDFS内のファイルが区切りテキスト・ファイルである(フィールドはカンマやタブなどの単一文字のマーカーを使用して区切る必要があります)と同時に、空間データがGeoJSONまたはWKT形式で格納されている場合に適用されます。 - Hive表を使用したOracle SQL Connector for HDFSの使用
Oracle SQL Connector for HDFS (OSCH)は、HDFSで定義されたHIVE表を直接サポートします。 - Oracle Loader for Hadoopによって生成されたファイルを使用したOracle SQL Connector for HDFSの使用
Oracle Loader for Hadoop (OLH)によって生成されたファイルを使用してOracle SQL Connector for HDFS (OSCH)を使用するには、OLHを使用してHDFSからOracle Databaseにデータを移動する方法を理解する必要があります。 - Oracle Big Data SQLを使用したOracle DatabaseとのHDFS空間データの統合
Oracle Big Data SQLを使用して、HDFSとOracle Databaseとの間の空間データのアクセスを容易にすることができます。
3.1 区切りテキスト・ファイルを使用したOracle SQL Connector for HDFSの使用
このトピックは、HDFS内のファイルが区切りテキスト・ファイルである(フィールドはカンマやタブなどの単一文字のマーカーを使用して区切る必要があります)と同時に、空間データがGeoJSONまたはWKT形式で格納されている場合に適用されます。
このようなデータがBig Data Spatial and Graphによって使用され、Oracle SQL Connector for HDFSを使用してOracleデータベースからアクセスされる場合、特定の構成ステップが必要です。
この例では、次のように、改行によって区切られたレコードがHDFS内のファイルに含まれ、各レコード内のフィールドがタブによって区切られていることを前提としています。
"6703" 1 62 "Hong Kong" 3479846 POINT (114.18306 22.30693) "6702" 57 166 "Singapore" 1765655 POINT (103.85387 1.29498)
-
Hadoopクラスタのノードにログインします。
-
次の例のように、OSCH (Oracle SQL Connector for HDFS)に必要な構成ファイルを作成します。
<?xml version="1.0"?> <configuration> <property> <name>oracle.hadoop.exttab.tableName</name> <value>TWEETS_EXT_TAB_FILE</value> </property> <property> <name>oracle.hadoop.exttab.sourceType</name> <value>text</value> </property> <property> <name>oracle.hadoop.exttab.dataPaths</name> <value>/user/scott/simple_tweets_data/*.log</value> </property> <property> <name>oracle.hadoop.connection.url</name> <value>jdbc:oracle:thin:@//myhost:1521/myservicename</value> </property> <property> <name>oracle.hadoop.connection.user</name> <value>scott</value> </property> <property> <name>oracle.hadoop.exttab.fieldTerminator</name> <value>\u0009</value> </property> <property> <name>oracle.hadoop.exttab.columnNames</name> <value>ID,FOLLOWERS_COUNT,FRIENDS_COUNT,LOCATION,USER_ID,GEOMETRY</value> </property> <property> <name>oracle.hadoop.exttab.defaultDirectory</name> <value>TWEETS_DT_DIR</value> </property> </configuration>
-
構成ファイルに
tweets_text.xml
という名前を付けます。 -
Hadoopクラスタのノード上で、次のコマンドを実行します。
hadoop jar $OSCH_HOME/jlib/orahdfs.jar \ oracle.hadoop.exttab.ExternalTable \ -conf /home/oracle/tweets_text.xml \ -createTable
コマンドを実行すると、データベース・パスワードを要求されます。
OSCH_HOME環境変数を作成することも、コマンド構文のOSCH_HOMEをOracle SQL Connector for HDFSのインストール・ディレクトリのフル・パスに置き換えることもできます。Oracle Big Data Applianceの場合、このディレクトリは
/opt/oracle/orahdfs-version
です
これで、表TWEETS_EXT_TAB_FILEに対して問い合せることが可能になります。データベースから他の任意の表と同じように問い合せることができます。このデータベースは、前述のステップで構成ファイルに指定されているターゲット・データベースです。次の問合せでは、表内の行の数を選択します。
select count(*) from TWEETS_EXT_TAB_FILE;
データベース内の他の任意の空間表の場合と同じように、この表に対して空間操作を実行できます。次の例では、特定の映画館から半径4分の1マイル(0.25マイル)内でツイートしているユーザーに関する情報を取得します。
select sdo_geom.SDO_DISTANCE(ci.geometry, SDO_GEOMETRY(tw.geometry, 8307), 0.05, 'UNIT=MILE'), ci.name, tw.user_id
from CINEMA ci, TWEETS_EXT_TAB_FILE tw where SDO_WITHIN_DISTANCE(ci.geometry, SDO_GEOMETRY(tw.geometry, 8307), 'DISTANCE=0.25 UNIT=MILE') = 'TRUE'
ここでは、表CINEMAはOracleデータベース内の空間表であり、HDFS表TWEETS_EXT_TAB_FILEを使用してこの表に対して問い合せることができます。ツイート表からのデータはWKT (Well-Known Text)として読み込まれ、SDO_GEOMETRYのWKTコンストラクタを使用してこのデータがデータベース内のジオメトリとしてマテリアライズされます。
ジオメトリのSRIDは8307です。また、空間データがGeoJSON形式である場合、問合せは次のようにする必要があります。
select sdo_geom.SDO_DISTANCE(ci.geometry, SDO_UTIL.FROM_GEOJSON(tw.geometry, '', 8307), 0.05, 'UNIT=MILE'), ci.name, tw.user_id
from CINEMA ci, TWEETS_EXT_TAB_FILE tw where SDO_WITHIN_DISTANCE(ci.geometry, SDO_UTIL.FROM_GEOJSON(tw.geometry, '', 8307), 'DISTANCE=0.25 UNIT=MILE') = 'TRUE'
3.2 Hive表を使用したOracle SQL Connector for HDFSの使用
Oracle SQL Connector for HDFS (OSCH)は、HDFSで定義されたHIVE表を直接サポートします。
Hive表は、パーティション化せずに、ROW FORMAT DELIMITED and FILE FORMAT TEXTFILE句を使用して定義する必要があります。空間データは、GeoJSONまたはWKT形式である必要があります。
Hive管理表とHive外部表はどちらもサポートされます。
たとえば、「区切りテキスト・ファイルを使用したOracle SQL Connector for HDFSの使用」で説明されているファイル上で表を作成するためのHiveコマンドは、次のとおりです。ここでは、HDFSデータに定義されたHive表をユーザーがすでに所有していることが前提です。HDFS内のデータがサポート対象の形式である必要があり、空間データがGeoJSONまたはWKT形式である必要があります。
CREATE EXTERNAL TABLE IF NOT EXISTS TWEETS_HIVE_TAB(
ID string,
FOLLOWERS_COUNT int,
FRIENDS_COUNT int,
LOCATION string,
USER_ID int,
GEOMETRY string)
ROW FORMAT DELIMITED
FIELDS TERMINATED BY '\t'
STORED AS INPUTFORMAT
'org.apache.hadoop.mapred.TextInputFormat'
OUTPUTFORMAT
'org.apache.hadoop.hive.ql.io.HiveIgnoreKeyTextOutputFormat'
LOCATION
'/user/scott/simple_tweets_data';
次の例では、表に対して問い合せます。
select ID, FOLLOWERS_COUNT, FRIENDS_COUNT, LOCATION, USER_ID, GEOMETRY from TWEETS_HIVE_TAB limit 10;
出力内容は次のようになります。
"6703" 1 62 "Hong Kong" 3479846 POINT (114.18306 22.30693) "6702" 57 166 "Singapore" 1765655 POINT (103.85387 1.29498)
-
Hadoopクラスタのノードにログインします。
-
次の例のように、OSCH (Oracle SQL Connector for HDFS)に必要な構成ファイルを作成します。
<?xml version="1.0"?> <configuration> <property> <name>oracle.hadoop.exttab.tableName</name> <value>TWEETS_EXT_TAB_HIVE</value> </property> <property> <name>oracle.hadoop.exttab.sourceType</name> <value>hive</value> </property> <property> <name>oracle.hadoop.exttab.hive.tableName</name> <value>TWEETS_HIVE_TAB</value> </property> <property> <name>oracle.hadoop.exttab.hive.databaseName</name> <value>default</value> </property> <property> <name>oracle.hadoop.connection.url</name> <value>jdbc:oracle:thin:@//myhost:1521/myservicename</value> </property> <property> <name>oracle.hadoop.connection.user</name> <value>scott</value> </property> <property> <name>oracle.hadoop.exttab.defaultDirectory</name> <value>TWEETS_DT_DIR</value> </property> </configuration>
-
構成ファイルに
tweets_text.xml
という名前を付けます。 -
Hadoopクラスタのノード上で、次のコマンドを実行します。
# Add HIVE_HOME/lib* to HADOOP_CLASSPATH. export HADOOP_CLASSPATH=$HADOOP_CLASSPATH:$HIVE_HOME/lib/* hadoop jar $OSCH_HOME/jlib/orahdfs.jar \ oracle.hadoop.exttab.ExternalTable \ -conf /home/oracle/tweets_hive.xml \ -createTable
コマンドを実行すると、データベース・パスワードを要求されます。OSCH_HOME環境変数を作成することも、コマンド構文のOSCH_HOMEをOracle SQL Connector for HDFSのインストール・ディレクトリのフル・パスに置き換えることもできます。Oracle Big Data Applianceの場合、このディレクトリは
/opt/oracle/orahdfs-version
ですHiveインストール・ディレクトリを指し示すように環境変数HIVE_HOMEを設定します(
/usr/lib/hive
など)。
これで、表TWEETS_EXT_TAB_FILEに対して問い合せることが可能になります。データベースから他の任意の表と同じように問い合せることができます。次の問合せでは、表内の行の数を選択します。
select count(*) from TWEETS_EXT_TAB_HIVE;;
データベース内の他の任意の空間表の場合と同じように、この表に対して空間操作を実行できます。次の例では、特定の映画館から半径4分の1マイル(0.25マイル)内でツイートしているユーザーに関する情報を取得します。
select sdo_geom.SDO_DISTANCE(ci.geometry, SDO_GEOMETRY(tw.geometry, 8307), 0.05, 'UNIT=MILE), ci.name, tw.user_id
from CINEMA ci, TWEETS_EXT_TAB_HIVE tw where SDO_WITHIN_DISTANCE(ci.geometry, SDO_GEOMETRY(tw.geometry, 8307), 'DISTANCE=0.25 UNIT=MILE') = 'TRUE'
ここでは、表CINEMAはOracleデータベース内の空間表であり、HDFS表TWEETS_EXT_TAB_FILEを使用してこの表に対して問い合せることができます。ツイート表からのデータはWKT (Well-Known Text)として読み込まれ、SDO_GEOMETRYのWKTコンストラクタを使用してこのデータがデータベース内のジオメトリとしてマテリアライズされます。
ジオメトリのSRIDは8307です。また、空間データがGeoJSON形式である場合、問合せは次のようにする必要があります。
select sdo_geom.SDO_DISTANCE(ci.geometry, SDO_UTIL.FROM_GEOJSON(tw.geometry, '', 8307), 0.05, 'UNIT=MILE), ci.name, tw.user_id
from CINEMA ci, TWEETS_EXT_TAB_HIVE tw where SDO_WITHIN_DISTANCE(ci.geometry, SDO_UTIL.FROM_GEOJSON(tw.geometry, '', 8307), 'DISTANCE=0.25 UNIT=MILE') = 'TRUE'
3.3 Oracle Loader for Hadoopによって生成されたファイルを使用したOracle SQL Connector for HDFSの使用
Oracle Loader for Hadoop (OLH)によって生成されたファイルを使用してOracle SQL Connector for HDFS (OSCH)を使用するには、OLHを使用してHDFSからOracle Databaseにデータを移動する方法を理解する必要があります。
Big Data Spatial and Graph空間データをデータベースに移動するには、変更が必要です。通常、このソリューションは、HDFS内の任意の種類のファイルまたは任意の種類のHiveデータに適用されます。空間情報は、ウェル・ノウン形式またはカスタム形式にすることができます。
最初は、空間情報がユーザー定義の形式で含まれるHDFS内のファイルから外部表を作成する方法の例です。HDFS内のファイルには次の形式のレコードが含まれることを前提とします。
{ "type":"Feature", "id":"6703", "followers_count":1, "friends_count":62, "location":"Hong Kong", "user_id":3479846, "longitude":114.18306, "latitude":22.30693 } { "type":"Feature", "id":"6702", "followers_count":57, "friends_count":166, "location":"Singapore", "user_id":1765655, "longitude":103.85387, "latitude":1.29498 }
これらのレコード用の表を作成するためのHiveコマンドは、次のとおりです。
add jar
/opt/oracle/oracle-spatial-graph/spatial/vector/jlib/ojdbc8.jar
/opt/oracle/oracle-spatial-graph/spatial/vector/jlib/sdoutl.jar
/opt/oracle/oracle-spatial-graph/spatial/vector/jlib/sdoapi.jar
/opt/oracle/oracle-spatial-graph/spatial/vector/jlib/sdohadoop-vector.jar
/opt/oracle/oracle-spatial-graph/spatial/vector/jlib/sdohadoop-vector-hive.jar
��� (add here jars containing custom SerDe and/or InputFormats);
CREATE EXTERNAL TABLE IF NOT EXISTS CUST_TWEETS_HIVE_TAB (id STRING, geometry STRING, followers_count STRING, friends_count STRING, location STRING, user_id STRING)
ROW FORMAT SERDE 'mypackage.TweetsSerDe'
STORED AS INPUTFORMAT 'oracle.spatial.hadoop.vector.geojson.mapred.GeoJsonInputFormat'
OUTPUTFORMAT 'org.apache.hadoop.hive.ql.io.HiveIgnoreKeyTextOutputFormat'
LOCATION '/user/scott/simple_tweets_data';
InputFormat
オブジェクトoracle.spatial.hadoop.vector.geojson.mapred.GeoJsonInputFormat
は、これらのレコードが厳密なGeoJSONでない場合でも、これらを読み込むことができます。このため、前述の例では、カスタムInputFormat
仕様は必要ありません。ただし、経度および緯度をWKTまたはGeoJSONジオメトリに変換するためのカスタムHive Serializer and Deserializer (SerDe)は必要です。そのためには、次の例のように、SerDeのデシリアライズ関数でSpatial Java APIを使用できます
@Override
public Object deserialize(Writable w) throws SerDeException {
Text rowText = (Text) w;
List<Text> row = new ArrayList<Text>(columnNames.size());
//default all values to null
for(int i=0;i<columnNames.size();i++){
row.add(null);
}
// Try parsing row into JSON object
JsonNode recordNode = null;
try {
String txt = rowText.toString().trim();
recordNode = jsonMapper.readTree(txt);
row.set(columnNames.indexOf("id"), new Text(recordNode.get("id").getTextValue()));
row.set(columnNames.indexOf("followers_count"), new Text(recordNode.get("followers_count").toString()));
row.set(columnNames.indexOf("friends_count"), new Text(recordNode.get("friends_count").toString()));
row.set(columnNames.indexOf("location"), new Text(recordNode.get("location").getTextValue()));
row.set(columnNames.indexOf("user_id"), new Text(recordNode.get("user_id").toString()));
Double longitude = recordNode.get("longitude").getDoubleValue();
Double latitude = recordNode.get("latitude").getDoubleValue();
//use the Spatial API to create the geometry
JGeometry geom = JGeometry.createPoint(new double[]{
longitude,
latitude},
2, //dimensions
8307 //SRID
);
//Transform the JGeometry to WKT
String geoWKT = new String(wkt.fromJGeometry(geom));
row.set(columnNames.indexOf("geometry"), new Text(geoWKT));
} catch (Exception e) {
throw new SerDeException("Exception parsing JSON: " +e.getMessage(), e);
}
return row;
}
前述の例では、ジオメトリをGeoJSON形式で返すために、置換元として次の部分を、
String geoWKT = new String(wkt.fromJGeometry(geom));
row.set(columnNames.indexOf("geometry"), new Text(geoWKT));
次のようにします。
row.set(columnNames.indexOf("geometry"), new Text(geom.toGeoJson()));
Spatial Java APIを使用してGeoJSON、WKTまたはESRI Shapefile内のデータを変換する別のSerDeの例は、フォルダ/opt/oracle/oracle-spatial-graph/spatial/vector/examples/hive/java/src/oracle/spatial/hadoop/vector/hive/java/src/serde
内にあります
次の例では、Hive表に対して問い合せます。
select ID, FOLLOWERS_COUNT, FRIENDS_COUNT, LOCATION, USER_ID, GEOMETRY from CUST_TWEETS_HIVE_TAB limit 10;
出力は次のようになります。
6703 1 62 Hong Kong 3479846 POINT (114.18306 22.30693) 6702 57 166 Singapore 1765655 POINT (103.85387 1.29498)
3.3.1 HDFSデータ・ポンプ・ファイルまたは区切りテキスト・ファイルの作成
「Oracle Loader for Hadoopによって生成されたファイルを使用したOracle SQL Connector for HDFSの使用」のHive表を使用して、HDFSデータ・ポンプ・ファイルまたは区切りテキスト・ファイルを作成できます。
-
次のように、Oracle Databaseに表を作成します。
CREATE TABLE tweets_t(id INTEGER PRIMARY KEY, geometry VARCHAR2(4000), followers_count NUMBER, friends_count NUMBER, location VARCHAR2(4000), user_id NUMBER);
この表は、ターゲット表として使用されます。Oracle Loader for HadoopはOracleデータベースの表のメタデータを使用して列名、データ型、パーティションおよび他の情報を識別します。簡単にするために、Hive表と同じ列(フィールド)を使用してこの表を作成します。外部表が作成された後、この表を削除することも、この表を使用して外部表からターゲット表に行を挿入することもできます。(ターゲット表の詳細は、「ターゲット表のメタデータについて」を参照してください。
-
次の例のように、ローダー構成ファイルを作成します。
<?xml version="1.0" encoding="UTF-8" ?> <configuration> <!-- Input settings --> <property> <name>mapreduce.inputformat.class</name> <value>oracle.hadoop.loader.lib.input.HiveToAvroInputFormat</value> </property> <property> <name>oracle.hadoop.loader.input.hive.databaseName</name> <value>default</value> </property> <property> <name>oracle.hadoop.loader.input.hive.tableName</name> <value>CUST_TWEETS_HIVE_TAB</value> </property> <!-- Output settings --> <property> <name>mapreduce.outputformat.class</name> <value>oracle.hadoop.loader.lib.output.DataPumpOutputFormat</value> </property> <property> <name>mapred.output.dir</name> <value>/user/scott/data_output</value> </property> <!-- Table information --> <property> <name>oracle.hadoop.loader.loaderMap.targetTable</name> <value>tweets_t</value> </property> <!-- Connection information --> <property> <name>oracle.hadoop.loader.connection.url</name> <value>jdbc:oracle:thin:@//myhost:1521/myservicename</value> </property> <property> <name>oracle.hadoop.loader.connection.user</name> <value>scott</value> </property> <property> <name>oracle.hadoop.loader.connection.password</name> <value>welcome1</value> <description> Having the password in cleartext is NOT RECOMMENDED. Use Oracle Wallet instead. </description> </property> </configuration>
この構成により、データ・ポンプ・ファイルがHDFSに作成されます。区切りテキスト・ファイルを出力として使用するには、置換元として次の部分を、
oracle.hadoop.loader.lib.output.DataPumpOutputFormat
次のようにします。
oracle.hadoop.loader.lib.output.DelimitedTextOutputFormat
-
構成ファイルに
tweets_hive_to_data_pump.xml
という名前を付けます。 -
データ・ポンプ・ファイルを作成します。
# Add HIVE_HOME/lib* and the Hive configuration directory to HADOOP_CLASSPATH. export HADOOP_CLASSPATH=$HADOOP_CLASSPATH:$HIVE_HOME/lib/*:$HIVE_CONF_DIR # Add Oracle Spatial libraries to HADOOP_CLASSPATH. export ORACLE_SPATIAL_VECTOR_LIB_PATH=/opt/oracle/oracle-spatial-graph/spatial/vector/jlib export HADOOP_CLASSPATH=$HADOOP_CLASSPATH:$ORACLE_SPATIAL_VECTOR_LIB_PATH/ojdbc8.jar:$ORACLE_SPATIAL_VECTOR_LIB_PATH/sdoutl.jar:$ORACLE_SPATIAL_VECTOR_LIB_PATH/sdoapi.jar:$ORACLE_SPATIAL_VECTOR_LIB_PATH/sdohadoop-vector.jar:$ORACLE_SPATIAL_VECTOR_LIB_PATH/sdohadoop-vector-hive.jar # The Oracle Spatial libraries need to be added to the libjars option as well. export LIBJARS=$ORACLE_SPATIAL_VECTOR_LIB_PATH/ojdbc8.jar,$ORACLE_SPATIAL_VECTOR_LIB_PATH/sdoutl.jar,$ORACLE_SPATIAL_VECTOR_LIB_PATH/sdoapi.jar,$ORACLE_SPATIAL_VECTOR_LIB_PATH/sdohadoop-vector.jar,$ORACLE_SPATIAL_VECTOR_LIB_PATH/sdohadoop-vector-hive.jar # And the following HIVE jar files have to be added to the libjars option. export LIBJARS=$LIBJARS,$HIVE_HOME/lib/hive-exec-*.jar,$HIVE_HOME/lib/hive-metastore-*.jar,$HIVE_HOME/lib/libfb303*.jar hadoop jar ${OLH_HOME}/jlib/oraloader.jar \ oracle.hadoop.loader.OraLoader \ -conf /home/oracle/tweets_hive_to_data_pump.xml \ -libjars $LIBJARS
前述の例の場合:
-
環境変数OLH_HOMEをインストール・ディレクトリに設定する必要があることを確認してください。
-
Hiveインストール・ディレクトリを指し示すように環境変数HIVE_HOMEを設定します(
/usr/lib/hive
など)。 -
Hive構成ディレクトリを指し示すように環境変数HIVE_CONF_DIRを設定します(
/etc/hive/conf
など)。 -
次のHive JARファイルを、カンマ区切りリスト形式で、
hadoop
コマンドの-libjars
オプションに追加します。アスタリスク(*)を完全なファイル名に置き換えます。hive-exec-*.jar hive-metastore-*.jar libfb303*.jar
-
oracle.kv.hadoop.hive.table.TableStorageHandler
を使用してHive表を(Oracle NoSQL Databaseから取得するデータを使用して)作成する場合、JARファイル$KVHOME/lib/kvclient.jar
(KVHOMEは、Oracle NoSQL Databaseがインストールされているディレクトリです)をhadoop
コマンドの-libjars
オプションに追加することも必要です。 -
org.apache.hadoop.hive.hbase.HBaseStorageHandler
を使用してHive表を(Apache HBaseから取得するデータを使用して)作成する場合、次のJARファイルを、カンマ区切りリスト形式で、hadoop
コマンドの-libjars
オプションに追加することも必要です。$HIVE_HOME/lib/hbase-server.jar $HIVE_HOME/lib/hive-hbase-handler.jar $HIVE_HOME/lib/hbase-common.jar $HIVE_HOME/lib/hbase-client.jar $HIVE_HOME/lib/hbase-hadoop2-compat.jar $HIVE_HOME/lib/hbase-hadoop-compat.jar $HIVE_HOME/lib/hbase-protocol.jar $HIVE_HOME/lib/htrace-core.jar
3.3.2 SQL Connector for HDFSの作成
SQL Connector fo HDFSを作成するには、このトピックの手順を実行します。
-
次の例のように、SQL Connector for HDFSの構成ファイルを作成します。
<?xml version="1.0"?> <configuration> <property> <name>oracle.hadoop.exttab.tableName</name> <value>TWEETS_EXT_TAB_DP</value> </property> <property> <name>oracle.hadoop.exttab.sourceType</name> <value>datapump</value> </property> <property> <name>oracle.hadoop.exttab.dataPaths</name> <value>/user/scott/data_output/oraloader-0000*.dat</value> </property> <property> <name>oracle.hadoop.connection.url</name> <value>jdbc:oracle:thin:@//myhost:1521/myservicename</value> </property> <property> <name>oracle.hadoop.connection.user</name> <value>scott</value> </property> <property> <name>oracle.hadoop.exttab.defaultDirectory</name> <value>TWEETS_DT_DIR</value> </property> </configuration>
ファイルが区切りテキスト・ファイルである場合、「区切りテキスト・ファイルを使用したOracle SQL Connector for HDFSの使用」のステップを実行します。
-
構成ファイルに
tweets_ext_from_dp.xml
という名前を付けます。 -
外部表を作成します。
hadoop jar $OSCH_HOME/jlib/orahdfs.jar \ oracle.hadoop.exttab.ExternalTable \ -conf /home/oracle/tweets_ext_from_dp.xml\ -createTable
前述のコマンドでは、OSCH_HOME環境変数を作成することも、コマンドのOSCH_HOMEをOracle SQL Connector for HDFSのインストール・ディレクトリのフル・パスに置き換えることもできます。Oracle Big Data Applianceの場合、このディレクトリは
/opt/oracle/orahdfs-version
です
これで、表TWEETS_EXT_TAB_DPに対して問い合せることが可能になります。データベース内の他の任意の表と同じように問い合せることができます。次に例を示します。
select count(*) from TWEETS_EXT_TAB_DP;
この表に対して次の例のような空間操作を実行し、映画館の半径4分の1マイル以内でツイートしているユーザーを取得できます。
select sdo_geom.SDO_DISTANCE(ci.geometry, SDO_GEOMETRY(tw.geometry, 8307), 0.5, 'UNIT=YARD'), ci.name, tw.user_id
from CINEMA ci, TWEETS_EXT_TAB_DP tw where SDO_WITHIN_DISTANCE(ci.geometry, SDO_GEOMETRY(tw.geometry, 8307), 'DISTANCE=200 UNIT=MILE') = 'TRUE';
この情報をさらに使用して広告カスタマイズすることもできます。
ジオメトリのSRIDは8307です。また、空間データがGeoJSON形式である場合、問合せは次のようにする必要があります。
select sdo_geom.SDO_DISTANCE(ci.geometry, SDO_UTIL.FROM_GEOJSON(tw.geometry, '', 8307), 0.5, 'UNIT=YARD'), ci.name, tw.user_id
from CINEMA ci, TWEETS_EXT_TAB_DP tw where SDO_WITHIN_DISTANCE(ci.geometry, SDO_UTIL.FROM_GEOJSON(tw.geometry, '', 8307), 'DISTANCE=200 UNIT=MILE') = 'TRUE';
3.4 Oracle Big Data SQLを使用したOracle DatabaseとのHDFS空間データの統合
Oracle Big Data SQLを使用して、HDFSとOracle Databaseとの間の空間データ・アクセスを簡略化できます。
Oracle Big Data SQL内の空間機能を有効にするには、ファイルbigdata.properties
を更新し、末尾に次の行を追加します($ORACLE_SPATIAL_VECTOR_LIB_PATHはOracle Spatialライブラリへのパスに置き換えます)。
java.classpath.user=$ORACLE_SPATIAL_VECTOR_LIB_PATH/ojdbc8.jar: $ORACLE_SPATIAL_VECTOR_LIB_PATH/sdoutl.jar: $ORACLE_SPATIAL_VECTOR_LIB_PATH/sdoapi.jar: $ORACLE_SPATIAL_VECTOR_LIB_PATH/sdohadoop-vector.jar: $ORACLE_SPATIAL_VECTOR_LIB_PATH/sdohadoop-vector-hive.jar (Also add here jars containing custom SerDe and/or InputFormat specifications.)
ファイルがHDFS内にある場合、次のソリューションを使用できます。
Oracle NoSQL DatabaseまたはApache HBaseから空間データにアクセスする場合、「Big Data SQLを使用したHive表の使用によるOracle外部表の作成」のソリューションを使用できます。
Oracle Loader for Hadoop (OLH)によって生成されたファイルを使用してOracle SQL Connector for HDFS (OSCH)を使用するには、OLHを使用してHDFSからOracle Databaseにデータを移動する方法を理解する必要があります。
Big Data Spatial and Graph空間データをデータベースに移動するには、変更が必要です。通常、このソリューションは、HDFS内の任意の種類のファイルまたは任意の種類のHiveデータに適用されます。空間情報は、ウェル・ノウン形式またはカスタム形式にすることができます。
最初は、空間情報がユーザー定義の形式で含まれるHDFS内のファイルから外部表を作成する方法の例です。HDFS内のファイルには次の形式のレコードが含まれることを前提とします。
{ "type":"Feature", "id":"6703", "followers_count":1, "friends_count":62, "location":"Hong Kong", "user_id":3479846, "longitude":114.18306, "latitude":22.30693 } { "type":"Feature", "id":"6702", "followers_count":57, "friends_count":166, "location":"Singapore", "user_id":1765655, "longitude":103.85387, "latitude":1.29498 }
これらのレコード用の表を作成するためのHiveコマンドは、次のとおりです。
add jar
/opt/oracle/oracle-spatial-graph/spatial/vector/jlib/ojdbc8.jar
/opt/oracle/oracle-spatial-graph/spatial/vector/jlib/sdoutl.jar
/opt/oracle/oracle-spatial-graph/spatial/vector/jlib/sdoapi.jar
/opt/oracle/oracle-spatial-graph/spatial/vector/jlib/sdohadoop-vector.jar
/opt/oracle/oracle-spatial-graph/spatial/vector/jlib/sdohadoop-vector-hive.jar
��� (add here jars containing custom SerDe and/or InputFormats);
CREATE EXTERNAL TABLE IF NOT EXISTS CUST_TWEETS_HIVE_TAB (id STRING, geometry STRING, followers_count STRING, friends_count STRING, location STRING, user_id STRING)
ROW FORMAT SERDE 'mypackage.TweetsSerDe'
STORED AS INPUTFORMAT 'oracle.spatial.hadoop.vector.geojson.mapred.GeoJsonInputFormat'
OUTPUTFORMAT 'org.apache.hadoop.hive.ql.io.HiveIgnoreKeyTextOutputFormat'
LOCATION '/user/scott/simple_tweets_data';
InputFormat
オブジェクトoracle.spatial.hadoop.vector.geojson.mapred.GeoJsonInputFormat
は、これらのレコードが厳密なGeoJSONでない場合でも、これらを読み込むことができます。このため、前述の例では、カスタムInputFormat
仕様は必要ありません。ただし、経度および緯度をWKTまたはGeoJSONジオメトリに変換するためのカスタムHive Serializer and Deserializer (SerDe)は必要です。そのためには、次の例のように、SerDeのデシリアライズ関数でSpatial Java APIを使用できます
@Override
public Object deserialize(Writable w) throws SerDeException {
Text rowText = (Text) w;
List<Text> row = new ArrayList<Text>(columnNames.size());
//default all values to null
for(int i=0;i<columnNames.size();i++){
row.add(null);
}
// Try parsing row into JSON object
JsonNode recordNode = null;
try {
String txt = rowText.toString().trim();
recordNode = jsonMapper.readTree(txt);
row.set(columnNames.indexOf("id"), new Text(recordNode.get("id").getTextValue()));
row.set(columnNames.indexOf("followers_count"), new Text(recordNode.get("followers_count").toString()));
row.set(columnNames.indexOf("friends_count"), new Text(recordNode.get("friends_count").toString()));
row.set(columnNames.indexOf("location"), new Text(recordNode.get("location").getTextValue()));
row.set(columnNames.indexOf("user_id"), new Text(recordNode.get("user_id").toString()));
Double longitude = recordNode.get("longitude").getDoubleValue();
Double latitude = recordNode.get("latitude").getDoubleValue();
//use the Spatial API to create the geometry
JGeometry geom = JGeometry.createPoint(new double[]{
longitude,
latitude},
2, //dimensions
8307 //SRID
);
//Transform the JGeometry to WKT
String geoWKT = new String(wkt.fromJGeometry(geom));
row.set(columnNames.indexOf("geometry"), new Text(geoWKT));
} catch (Exception e) {
throw new SerDeException("Exception parsing JSON: " +e.getMessage(), e);
}
return row;
}
前述の例では、ジオメトリをGeoJSON形式で返すために、置換元として次の部分を、
String geoWKT = new String(wkt.fromJGeometry(geom));
row.set(columnNames.indexOf("geometry"), new Text(geoWKT));
次のようにします。
row.set(columnNames.indexOf("geometry"), new Text(geom.toGeoJson()));
Spatial Java APIを使用してGeoJSON、WKTまたはESRI Shapefile内のデータを変換する別のSerDeの例は、フォルダ/opt/oracle/oracle-spatial-graph/spatial/vector/examples/hive/java/src/oracle/spatial/hadoop/vector/hive/java/src/serde
内にあります
次の例では、Hive表に対して問い合せます。
select ID, FOLLOWERS_COUNT, FRIENDS_COUNT, LOCATION, USER_ID, GEOMETRY from CUST_TWEETS_HIVE_TAB limit 10;
出力は次のようになります。
6703 1 62 Hong Kong 3479846 POINT (114.18306 22.30693) 6702 57 166 Singapore 1765655 POINT (103.85387 1.29498)
3.4.1 Big Data SQLを使用したHDFSファイル用のOracle外部表の作成
HDFS内の任意の種類のファイル用としてOracle外部表を作成できます。空間情報は、ウェル・ノウン形式またはカスタム形式にすることができます。
ジオメトリ形式がWKTまたはGeoJSONでない場合、フォルダ/opt/oracle/oracle-spatial-graph/spatial/vector/examples/hive/java/src/oracle/spatial/hadoop/vector/hive/java/src/serde
内に用意されているSerDeの例の1つを使用するか、「Oracle Loader for Hadoopによって生成されたファイルを使用したOracle SQL Connector for HDFSの使用」の例のようにカスタムSerDeを作成します。
その後、次の例のように、Oracle外部表を作成します。
CREATE TABLE SAMPLE_TWEETS (id VARCHAR2(4000),
geometry VARCHAR2(4000),
followers_count VARCHAR2(4000),
friends_count VARCHAR2(4000),
location VARCHAR2(4000), user_id VARCHAR2(4000)) ORGANIZATION EXTERNAL
(TYPE oracle_hdfs DEFAULT DIRECTORY DEFAULT_DIR
ACCESS PARAMETERS (
com.oracle.bigdata.rowformat: \
SERDE 'mypackage.TweetsSerDe'
com.oracle.bigdata.fileformat: \
INPUTFORMAT 'oracle.spatial.hadoop.vector.geojson.mapred.GeoJsonInputFormat' \
OUTPUTFORMAT 'org.apache.hadoop.hive.ql.io.HiveIgnoreKeyTextOutputFormat' \
)
LOCATION ('/user/scott/simple_tweets_data/*.log'));
これで、表SAMPLE_TWEETSに対して問い合せることが可能になります。データベース内の他の任意の表と同じように問い合せることができます。次に例を示します。
select count(*) from SAMPLE_TWEETS;
この表に対して次の例のような空間操作を実行し、映画館の半径4分の1マイル以内でツイートしているユーザーを取得できます。
select sdo_geom.SDO_DISTANCE(ci.geometry, SDO_GEOMETRY(tw.geometry, 8307), 0.5, 'UNIT=YARD'), ci.name, tw.user_id
from CINEMA ci, SAMPLE_TWEETS tw where SDO_WITHIN_DISTANCE(ci.geometry, SDO_GEOMETRY(tw.geometry, 8307), 'DISTANCE=200 UNIT=MILE') = 'TRUE';
この情報をさらに使用して広告カスタマイズすることもできます。
ジオメトリのSRIDは8307です。また、空間データがGeoJSON形式である場合、問合せは次のようにする必要があります。
select sdo_geom.SDO_DISTANCE(ci.geometry, SDO_UTIL.FROM_GEOJSON(tw.geometry, '', 8307), 0.5, 'UNIT=YARD'), ci.name, tw.user_id
from CINEMA ci, SAMPLE_TWEETS tw where SDO_WITHIN_DISTANCE(ci.geometry, SDO_UTIL.FROM_GEOJSON(tw.geometry, '', 8307), 'DISTANCE=200 UNIT=MILE') = 'TRUE';
3.4.2 Big Data SQLを使用したHive表の使用によるOracle外部表の作成
Big Data SQLを使用してHive表を使用してOracle外部表を作成できます。空間情報は、ウェル・ノウン形式またはカスタム形式にすることができます。
Oracle外部表を作成するために使用するHive表は、「Oracle Loader for Hadoopによって生成されたファイルを使用したOracle SQL Connector for HDFSの使用」で説明されているように作成する必要があります。
Hive表Oracleを使用して作成できるOracle外部表を作成します。次に例を示します。
CREATE TABLE SAMPLE_TWEETS (id VARCHAR2(4000), geometry VARCHAR2(4000), followers_count VARCHAR2(4000), friends_count VARCHAR2(4000), location VARCHAR2(4000), user_id VARCHAR2(4000)) ORGANIZATION EXTERNAL
(TYPE ORACLE_HIVE
DEFAULT DIRECTORY DEFAULT_DIR
ACCESS PARAMETERS (
com.oracle.bigdata.cluster=cluster
com.oracle.bigdata.tablename=default.CUST_TWEETS_HIVE_TAB)
) PARALLEL 2 REJECT LIMIT UNLIMITED;
これで、表SAMPLE_TWEETSに対して問い合せることが可能になります。データベース内の他の任意の表と同じように問い合せることができます。次に例を示します。
select count(*) from SAMPLE_TWEETS;
この表に対して次の例のような空間操作を実行し、映画館の半径4分の1マイル以内でツイートしているユーザーを取得できます。
select sdo_geom.SDO_DISTANCE(ci.geometry, SDO_GEOMETRY(tw.geometry, 8307), 0.5, 'UNIT=YARD'), ci.name, tw.user_id
from CINEMA ci, SAMPLE_TWEETS tw where SDO_WITHIN_DISTANCE(ci.geometry, SDO_GEOMETRY(tw.geometry, 8307), 'DISTANCE=200 UNIT=MILE') = 'TRUE';
この情報をさらに使用して広告カスタマイズすることもできます。
ジオメトリのSRIDは8307です。また、空間データがGeoJSON形式である場合、問合せは次のようにする必要があります。
select sdo_geom.SDO_DISTANCE(ci.geometry, SDO_UTIL.FROM_GEOJSON(tw.geometry, '', 8307), 0.5, 'UNIT=YARD'), ci.name, tw.user_id
from CINEMA ci, SAMPLE_TWEETS tw where SDO_WITHIN_DISTANCE(ci.geometry, SDO_UTIL.FROM_GEOJSON(tw.geometry, '', 8307), 'DISTANCE=200 UNIT=MILE') = 'TRUE';