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)を参照してください。
このトピックは、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'
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'
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)
「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
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';
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)
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';
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';