人生の恥は書き捨て

プログラムとかいろいろ

Apache Solrをデータインポートハンドラでmysqlと同期する

はじめに

solrのインストールについては以前書きました。
Apache Solrのインストール - 人生の恥は書き捨て

今回は、mysqlのデータをデータインポートハンドラを使ってsolrに取り込みます。

環境

solr 4.9.0
mysql 5.6.19

Apache Solrをデータインポートハンドラでmysqlと同期

ライブラリのインストール

solrはjavaで動いているので、
mysqlサーバーにアクセスするためにmysql-connector-javaを入れます。

cd /usr/local/src
wget http://dev.mysql.com/get/Downloads/Connector-J/mysql-connector-java-5.1.31.tar.gz/from/http://cdn.mysql.com/
tar -zxvf index.html
mv mysql-connector-java-5.1.31-bin.jar /usr/local/solr/example/lib/mysql-connector-java-5.1.31-bin.jar

パスを通します。

vim /usr/local/solr/example/solr/collection1/conf/solrconfig.xml

<lib dir="../../../contrib/extraction/lib" regex=".*\.jar" />
<lib dir="../../../dist/" regex="solr-cell-\d.*\.jar" />

<lib dir="../../../contrib/clustering/lib/" regex=".*\.jar" />
<lib dir="../../../dist/" regex="solr-clustering-\d.*\.jar" />

<lib dir="../../../contrib/langid/lib/" regex=".*\.jar" />
<lib dir="../../../dist/" regex="solr-langid-\d.*\.jar" />

<lib dir="../../../contrib/velocity/lib" regex=".*\.jar" />
<lib dir="../../../dist/" regex="solr-velocity-\d.*\.jar" />
<!-- Additional Setting -->
<lib dir="../../lib/" regex="mysql-connector-java-\d.*\.jar" />
<lib dir="../../../dist/" regex="solr-dataimporthandler-\d.*\.jar" />
<lib dir="../../../contrib/dataimporthandler/lib/" regex=".*\.jar" />

80行目くらいにライブラリの読み込みの記述があるので、
そこにAdditional Setting以下の3行を足します。

これでmysqlと連携できます。

データベースの準備


データベースを用意します。

mysql> DESC member;
+-------------+------------------+------+-----+-------------------+-----------------------------+
| Field       | Type             | Null | Key | Default           | Extra                       |
+-------------+------------------+------+-----+-------------------+-----------------------------+
| id          | int(11) unsigned | NO   | PRI | NULL              | auto_increment              |
| name        | varchar(32)      | YES  |     | NULL              |                             |
| updated     | timestamp        | NO   |     | CURRENT_TIMESTAMP | on update CURRENT_TIMESTAMP |
| catchPhrase | text             | YES  |     | NULL              |                             |
+-------------+------------------+------+-----+-------------------+-----------------------------+


中にダミーのデータを入れておきます。

mysql> select * from member;
+----+----------------+---------------------+--------------------------------------------+
| id | name           | updated             | catchPhrase                                |
+----+----------------+---------------------+--------------------------------------------+
|  1 | Honoka Kosaka  | 2014-08-07 13:40:51 | ファイトだよ!                             |
|  2 | Umi Sonoda     | 2014-08-07 13:41:26 | ラブアローシュート!                       |
|  3 | Kotori Minami  | 2014-08-07 13:43:11 | はいちゅんちゅん(・8・)                 |
|  4 | Hanayo Koizumi | 2014-08-07 13:41:41 | だれかたすけてー!                         |
|  5 | Rin Hoshizora  | 2014-08-07 13:43:28 | にゃんにゃんにゃ〜ん                       |
|  6 | Maki Nishikino | 2014-08-07 13:41:58 | まきちゃんかわいいかきくけこ               |
+----+----------------+---------------------+--------------------------------------------+

データインポートの設定

データインポートの設定ファイルを宣言

vim /usr/local/solr/example/solr/collection1/conf/solrconfig.xml
ファイル末尾のの前に

<requestHandler name="/dataimport" class="org.apache.solr.handler.dataimport.DataImportHandler">
  <lst name="defaults">
    <str name="config">data-config.xml</str>
  </lst>
</requestHandler>

を追加します。
ここで、data-config.xmlにデータインポートの設定を書くよ、と宣言しています。

schema.xml

solrにどのようにデータを保存してインデックスをつけていくかを設定します。
デフォルトで設定がたくさん書いてあるので、それを使ってもいいです。
自分はこのようにしました。

<?xml version="1.0" encoding="UTF-8" ?>
<schema name="lovelive" version="1.4">
<field name="_version_" type="long" indexed="true" stored="true"/>
<types>
  <fieldType name="long" class="solr.LongField" omitNorms="true" />
  <fieldType name="string" class="solr.StrField" sortMissingLast="true" omitNorms="true" />
  <fieldType name="timestamp" class="solr.TrieDateField" />
  <fieldType name="text_cjk" class="solr.TextField">
    <analyzer class="org.apache.lucene.analysis.cjk.CJKAnalyzer" />
  </fieldType>
  <fieldType name="text_ja" class="solr.TextField">
    <analyzer> 
      <tokenizer class="solr.JapaneseTokenizerFactory" mode="search"/>
      <filter class="solr.JapaneseBaseFormFilterFactory"/>
      <filter class="solr.JapanesePartOfSpeechStopFilterFactory" tags="lang/stoptags_ja.txt" enablePositionIncrements="true"/>
      <filter class="solr.CJKWidthFilterFactory"/>
      <filter class="solr.StopFilterFactory" ignoreCase="true" words="lang/stopwords_ja.txt" enablePositionIncrements="true" />
      <filter class="solr.JapaneseKatakanaStemFilterFactory" minimumLength="4"/>
      <filter class="solr.LowerCaseFilterFactory"/>
    </analyzer>  
  </fieldType>
</types>
 
<fields>
  <field name="id" type="long" indexed="true" stored="true" required="true" />
  <field name="name" type="text_ja"  indexed="true" stored="true" />
  <field name="catchPhrase" type="text_ja" indexed="true" stored="true" />
</fields>
 
<uniqueKey>id</uniqueKey>
<defaultSearchField>name</defaultSearchField>
<solrQueryParser defaultOperator="AND" />

</schema>

...ではデータの型を定義しています。
...ではフィールドを定義しています。
フィールドにはtypesで定義した型を設定します。
フィールドには更に、indexed、stored、などの属性が設定できます。
indexed: trueにすると、インデックス、ソートなどができる。
stored: 値をsolrに保存する。
などなど詳しくはここに英語ですが載っています。
SchemaXml - Solr Wiki
日本語の形態素解析はkuromojiを使用しています。

data-config.xml

データをインポートするときのmysqlの設定を書いていきます。

<dataConfig>
  <dataSource name="ratings" driver="com.mysql.jdbc.Driver" url="jdbc:mysql://127.0.0.1:3306/lovelive" user="ユーザー名" password="パスワード" />
   
  <document>
    <entity name="member"
      query="select * from members"
      deltaQuery="select id from members where created >= '${dataimporter.last_index_time}'"
      deltaImportQuery="select * from members where id=${dataimporter.delta.id}">
      <field column="id" name="id" />
      <field column="name" name="name" />
      <field column="catchPhrase" name="catchPhrase" />
    </entity>
  </document>     
</dataConfig>

で接続するDBの設定をします。
でどのようにデータを取得するか設定します。
queryではfull-importする際のsqlを設定しています。
dataQueryとdataImportQueryではdelta-importする際のsqlを設定しています。

あとはsolrのメニューからcoreを選んで
dataImportをExcuteすればmysqlのデータをsolrにインポートできます。