読者です 読者をやめる 読者になる 読者になる

全文検索用のテストデータを用意する(twitter streaming api編)

全文検索Oracle TextやSolr)をちょっと試すだけならテスト用に一個、二個文章を入れて
検索出来たね。よかったねで終われるのですが、形態素解析N-gramを比較したい時や、
パフォーマンスを考慮したい等、テストデータの用意にとても困ります。


wikipediaのデータを加工して使うのも一つの手なんですが、
http://d.hatena.ne.jp/KNOPP/20120115/1326640025


今回はtechdb show caseで話題に挙がった twitter streaming apiを使いたいと思います。
twitter streaming apiを扱いやすいようにしたライブラリtwitter4Jが公開されているので
今回は、JavaOracle Databaseに入れます。
(全文検索はその後で)


今回、Javaプログラミング5年ぶりぐらいで随分手間取ったので健忘録も含めて詳しく書きます。


JDK/JDBCドライバの用意
Oracle Client を「ランタイム」もしくは、「管理者」でインストールするとJDK/JDBCともにインストールされているので
今回はそれを使用します。


・twitter4Jの用意
http://twitter4j.org/ja/index.html#download
からダウンロードして解凍しておきます。
(今回はC:\twitterに解凍します)


Oracleユーザ/テーブルの用意
今回はtwitterというユーザを用意し、streamというテーブルを作成します。

SQL>connect /as sysdba
SQL>create user twitter identified by twitter;
SQL>GRANT connect, resource TO twitter;
SQL>connect twitter/twitter
SQL>@create_table


create_table.sql

create table stream(
id number,
Name varchar2(100),
ScreenName varchar2(100),
text varchar2(300),
CreatedAt varchar2(100)
);


・プログラムの作成
twitter4jを使う部分については、ほぼ全面的に@teapipinさんの 「 【Twitter4J】Twitterの全ユーザーの公開ツイート(日本のみ)を表示する方法(その2、Streaming APIのsample)」を使わせて頂きました。
JDBCOracle)については、Oracleのマニュアルを適当に。
例外処理は垂れ流しですw


Twitter2DB.java

import twitter4j.*;
import twitter4j.auth.BasicAuthorization;
import java.sql.*;
import oracle.jdbc.*;
import oracle.jdbc.pool.*;
import java.text.*;


public class Twitter2DB {
    public static void main(String[] args){
        try{
        	String AuthUser = args[0];
        	String AuthPass = args[1];
        	String JdbcUrl = "jdbc:oracle:thin:"+args[2];
            //TwitterStream twitterstream = new TwitterStreamFactory().getInstance(); 
            //何故かうまくいかないのでBasic認証に切り替え
            TwitterStream twitterstream = new TwitterStreamFactory().getInstance(new BasicAuthorization(AuthUser,AuthPass));
            twitterstream.addListener(new MyStatusAdapter(JdbcUrl));
            twitterstream.sample();

        } catch(Exception e){
            e.printStackTrace();
        }
    }
}

//コンソール出力&テーブルにInsert
class MyStatusAdapter extends StatusAdapter {
	
	Connection conn;
	PreparedStatement pstmt;
	
	MyStatusAdapter(String Url){
		try{
			OracleDataSource ods = new OracleDataSource();
       		ods.setURL(Url);
        	conn = ods.getConnection();
			pstmt = conn.prepareStatement ("insert into stream (ID,NAME,SCREENNAME,TEXT,CREATEDAT) values (?, ?,?,?,?)");
		}catch(Exception e){
			e.printStackTrace();
		}
	}
	
	  public void onStatus(Status status){

        //ユーザの情報を取得
        User user = status.getUser();

		if (user.getTimeZone() != null && (user.getTimeZone().equals("Tokyo") || user.getTimeZone().equals("Osaka") ||user.getTimeZone().equals("Sapporo"))){
			DateFormat df = new SimpleDateFormat("yyyy/MM/dd HH:mm:ss.SSS");
			try{
				pstmt.setLong   (1, status.getId() );
    			pstmt.setString (2, user.getName());
				pstmt.setString (3, user.getScreenName());
				pstmt.setString (4, status.getText());
                                //status.getCreatedAtがDate型でうまく変換できないのでStringでフォーマットしてしまう。
				pstmt.setString (5,df.format(status.getCreatedAt()));
				pstmt.execute ();
			}catch(Exception e){
				e.printStackTrace();
			}    			
		}
    }
}


・PATH/CLASSPATHの設定
IDEでやれば楽ちんなのですが、今回 notepad+javacでプログラム書いたので、
PATH/CLASSPATHの設定も行っておきます。
Oracle ClientはC:\app\Administrator\product\11.2.0\client_1にインストールされており、
twitter4jのライブラリはC:\twitter\libにある前提です。

JDBCプログラミングに必要なライブラリはojdbc5.jar*、orai18n.jar
twitter streaming apiに必要なtwitter4jライブラリはtwitter4j-core-3.0.1.jar、twitter4j-stream-3.0.1.jarです。


Oracle Client(11.2.0.1)に付属のjavacは1.5であるため、ojdbc5.jarを使用(javacが1.6だったらojdbc6.jar)

set PATH=%PATH%;C:\app\Administrator\product\11.2.0\client_1\jdk\bin
set CLASSPATH=.;C:\twitter\lib\twitter4j-stream-3.0.1.jar;C:\twitter\lib\twitter4j-core-3.0.1.jar;C:\app\Administrator\product\11.2.0\client_1\jdbc\lib\ojdbc5.jar;C:\app\Administrator\product\11.2.0\client_1\jlib\orai18n.jar


コンパイル

javac Twitter2DB.java


・プログラムの実行
こんな感じで実行します。
java Twitter2DB twitterのID twitterのパスワード dbuser/dbpass@ホスト:ポート:Oracleサービス名


実行例

java Twitter2DB twitterID twitterPASS twitter/twitter@192.168.1.22:1521:ORCL


あとは、日本語の公開ツイートがコンソール上に流れ、テーブルにもインサートされます。

だいたい10日ほどプログラム動かしっぱなしにすると、
230万ツイートぐらい集まって、
Oracleのデータファイルが300MB程になりました。