ElasticsearchへMySQLのデータを流し込みたかったのでriverプラグインを使ったが、いくつかハマりどころがあったのでメモとして残す。
Elasticsearchに関連するツールのバージョンは要確認
関連するプラグインやライブラリのバージョンが少しでも違うと動かなくなる。
- Elasticsearch 1.3.4の場合: riverは1.3.4.4, kuromojiは2.3.0
- Elasticsearch 1.4.0の場合: riverは1.4.0.3.Beta1, kuromojiは2.4.0
mysql-connector-javaは最新を入れた方がよい。elasticsearch 1.4.0の時は5.1.33を入れた。
また、Macの場合jdk-1.7.0以上でないと動かないので、jdk7を入れる。 http://download.oracle.com/otn-pub/java/jdk/7u71-b14/jdk-7u71-macosx-x64.dmg
mappingについて
mappingなくても動くし書かなくていいかな、と思ってた。 でも運用する場合、フィールド毎にanalyzerの設定等を行う場合があり、どのみち必要になる。 最初からmappingは書こう。ただし、読み込むテーブルの全てのカラムでなく、必要なカラムだけで良い。
joinテーブルではSQLのエイリアスでフィールド名をキレイに
joinしたテーブルを読み込む場合、sql側でエイリアスを使うとフィールド名をキレイにできた。
{
"type": "jdbc",
"jdbc": {
"url": "jdbc:mysql://localhost/test",
"user": "root",
"password": "",
"sql": "select p.id product_id, p.name, product_name, od.quantity from products p inner join order_details od on p.id = od.product_id"
"index": "test",
"type": "order",
"type_mapping": {
"order": {
"properties": {
"product_id": { "type": "long", "store":"yes" },
"product_name": { "type":"string", "store":"yes", "index":"analyzed"},
"quantity": { "type": "long", "store":"yes" }
}
}
}
}
この例だと、productsテーブルのIDコラムはidという名前で登録されてしまうところだが、product_idというエイリアスを使えばtype_mappingでもその名前で登録できる。
riverプラグインがデータを流し込んでくれません!
riverは実行時に、river自体が使うインデックス(デフォルトだと_river
)と、それに加えてデータを流し込むインデックス(デフォルトだとjdbc
)を作成する。
動作を試しているときにanalyzer等の設定を修正したので、反映のためにjdbcインデックスを削除し、もう一回riverでDBを流し込むコマンドを打っても再度jdbcが作成されない。
ここでは、_river
インデックスも削除する必要がある。これすごい不親切で結構ハマった。
analyzerの設定もriverの設定ファイル内に書く
Elasticsearchの本を読むとanalyzerの設定用にcurlでjsonデータを送ったりしているが、riverでデータを流し込む場合、そのjsonデータにanalyzerを設定する。
以下のjsonのindex_settingsの部分がそれに当たる。
{
"type": "jdbc",
"jdbc": {
"url": "jdbc:mysql://localhost/test",
"user": "root",
"password": "",
"sql": "select p.id product_id, p.name, product_name, od.quantity from products p inner join order_details od on p.id = od.product_id",
"index": "test",
"type": "order",
"index_settings": {
"index": {
"analysis": {
"tokenizer": {
"kuromoji" : {
"type":"kuromoji_tokenizer"
}
},
"filter" : {
"synonym" : {
"type" : "synonym",
"synonyms_path": "synonyms.txt"
}
},
"analyzer": {
"kuromoji": {
"type":"custom",
"tokenizer": "kuromoji"
},
"kuromoji_synonym": {
"type":"custom",
"tokenizer": "kuromoji",
"filter" : ["synonym"]
}
}
}
},
"type_mapping": { ... }
}
}
synonyms.txt等の設定ファイルは$ES_HOME/configからの相対パスへ配置
synonyms filterを使う場合もriverの設定ファイルに記述するので、コマンドを叩くパスにsynonyms.txtがあればいいんじゃないか、なんて思ってた。 ドキュメント読んだら$ES_HOME/configの下にないと読み込んでくれませんってちゃんと書いてありました。。
curlコマンドを打つときは@表記を使ったほうがラク
入力するjsonデータをコマンドラインで打つのではなく、jsonデータをファイルにまとめ-d @test.json
のような形でcurlに渡そう。
$ curl -XPUT http://localhost:9200/_river/my_jdbc_river/_meta -d @test.json