ElasticSearch
MongoDB の全文検索機能が日本語に対応していないということで、ElasticSearchを使ってみた。
例えば東京都って文字があるときに、東京ではヒットしてほしいが京都ではヒットしてほしくないみたいな検索。
ElasticSearch は Java で動いていて、データをインデックス化して保持している。
MongoDB とつなげるためのプラグインを入れて、MongoDB から ElasticSearch にデータを流し込み同期しておく。
バージョンの依存関係が強いので、MongoDB のバージョンに合わせて各モジュールのバージョンを選ぶ。
・MongoDB 2.4.9
・ElasticSearch 1.1.1
・Kuromoji Analysis Plugin 2.1.0
・MongoDB River Plugin 2.0.0
・Attachments Plugin 2.0.0
インストールはpluginというスクリプトが同梱されてるので、楽。
wget https://download.elasticsearch.org/elasticsearch/elasticsearch/elasticsearch-1.1.1.tar.gz tar xzvf elasticsearch-1.1.1.tar.gz sudo mv Downloads/elasticsearch-1.1.1 /home/mera/ sudo ln -s /home/mera/elasticsearch-1.1.1 /home/mera/elasticsearch cd /home/mera/elasticsearch bin/plugin -install elasticsearch/elasticsearch-analysis-kuromoji/2.1.0 bin/plugin -install elasticsearch/elasticsearch-mapper-attachments/2.0.0 bin/plugin --install com.github.richardwilly98.elasticsearch/elasticsearch-river-mongodb/2.0.0
文章を単語に分けてくれる機能が Kuromoji プラグイン。
これをデフォルトで使ってくれるように、設定ファイル(config/elasticsearch.yml) に以下を追加しておく。
index.analysis.analyzer.default.type: custom index.analysis.analyzer.default.tokenizer: kuromoji_tokenizer
起動するときは、これでアクセスできるようになる。
/home/mera/elasticsearch/bin/elasticsearch -d
アクセスはHTTP経由で行うのが、ちょっと独特でおもしろいけど、RESTか。
ポートはデフォルトで 9200番。
$ curl -XPUT 'http://localhost:9200/test/' {"acknowledged":true}
でデータが格納される場所ができる。
この場合は “test” というデータベース的なものができる。
消すときは、
$ curl -XDELETE 'http://localhost:9200/test' {"acknowledged":true}
で、データは MongoDB から吸い上げたい。
そのためのプラグインが elasticsearch-river-mongodb
同期用の設定もPUTで書き込む。
こんな感じで、MongoDB にある “test” データベースを丸ごと、ElasticSearch の “test” に同期する。
$ curl -XPUT "localhost:9200/_river/test/_meta" -d ' { "type": "mongodb", "mongodb": { "db": "test", "servers": [ { "host": "127.0.0.1", "port": 27101 } ], "options": { "secondary_read_preference": true, "import_all_collections": true } }, "index": { "name": "test" } }'
シャットダウンするときは、プロセスをKillするんじゃなくて、POSTで指令。
$ curl -XPOST 'http://localhost:9200/_shutdown'
データを検索するときは、
$ curl -XGET "http://localhost:9200/test/_search"
とか、
curl -XGET 'http://localhost:9200/test/questions/_search?pretty=true' -d ' { "query" : { "simple_query_string" : { "fields": ["question_title"], "query": "難問 山", "default_operator": "and" } } }'
とか、いろいろ検索文は作れる。
どう組み立てていいかよくわからないときは、
bin/plugin -install mobz/elasticsearch-head
でプラグインを入れておくと、http://localhost:9200/_plugin/head/ でデータベースの中身が見れたり、
検索用のJSONクエリを「選択してボタン」って感じで作ることができたりして、わかりやすい。