##mongodb での全文検索
mongodbで日本語で全文検索したい!と思ってもこれが残念ながら未だ非対応です。※2015年10月
参考URL
そこでElasticSearch プラグイン(MongoDB River + Kuromoji Analysis)を利用します。
ElasticSearchからプラグインを色々使ってmongodbから全文検索する感じです。
そのためにいろいろとハマったのでメモ的に書いていきます。
必要なものは以下です。
- mongodb
- JDK (Java Development Kit)
- ElasticSearch
- MongoDB River Plugin (プラグイン)(mongodbの接続用)
- Kuromoji Analysis Plugin (プラグイン)(日本語形態素解析)
環境はCentOS 6.6 64bit です。
何度も言いますが、mongodbで日本語検索が出来れば必要ないものたちです。
##mongodbのインストール
/etc/yum.repos.d/mongodb.repoを作成してリポジトリを追加する。
[mongodb]
name=MongoDB Repository
baseurl=http://downloads-distro.mongodb.org/repo/redhat/os/x86_64/
gpgcheck=0
enabled=1
mongodbをインストールします。
sudo yum install mongodb-org
mongodbの起動
sudo yum service mongod start
##JDK のインストール
sudo yum install java-1.7.0-openjdk
問題はここからです。
##ElasticSearchのバージョンを決める
おそらく現時点ではmongodbは2.6.8あたりだと思うのでそのつもりで各自選択していきます。
####今回利用するバージョン
mongodb | ElasticSearch | Kuromoji Analysis Plugin | MongoDB River Plugin |
---|---|---|---|
2.6.8 | 1.3.9 | 2.3.0 | 2.0.2 |
バージョン気にせずインストールをするとなぜか動かなかったりしますのでご注意ください。
マイナーバージョンの違いくらいだったらなんとかなるのかもしれませんが、保証はありません。
無視してやるのもいいですが、その場合は出来る限り下のバージョンにした方がいいです。
しかし、何度も言いますが、mongodbで日本語検索が出来れば必要ないものたちです。
##ElasticSearch1.3.xのインストール
/etc/yum.repos.d/elasticsearch.repoを作成してリポジトリを追加します。
[elasticsearch-1.3.x]
name=Elasticsearch repository for 1.3.x packages
baseurl=http://packages.elasticsearch.org/elasticsearch/1.3/centos
gpgcheck=1
gpgkey=http://packages.elasticsearch.org/GPG-KEY-elasticsearch
enabled=1
###ElasticSearchのインストール
sudo yum install elasticsearch
とりあえず起動する
sudo service elasticsearch
起動確認
curl -XGET 'localhost:9200'
{
"status" : 200,
"name" : "Zeitgeist",
"version" : {
"number" : "1.3.9",
"build_hash" : "0915c7306e6264ba21a6cb7609b93545ccc32ef1",
"build_timestamp" : "2015-02-19T12:34:48Z",
"build_snapshot" : false,
"lucene_version" : "4.9"
},
"tagline" : "You Know, for Search"
}
##MongoDB River Plugin 2.0.2 のインストール
sudo /usr/share/elasticsearch/bin/plugin --install com.github.richardwilly98.elasticsearch/elasticsearch-river-mongodb/2.0.2
##Kuromoji Analysis Plugin 2.3.0のインストール
###インストール
sudo /usr/share/elasticsearch/bin/plugin --install elasticsearch/elasticsearch-analysis-kuromoji/2.3.0
/etc/elasticsearch/elasticsearch.ymlを編集
index.analysis.analyzer.default.type: custom # 追加
index.analysis.analyzer.default.tokenizer: kuromoji_tokenizer # 追加
##ElasticSearchの再起動
sudo service elasticsearch restart
ふぅ、何度も言いますが、mongodbで日本語検索が出来れば(略
##mongodbをレプリカセットで構築する
###レプリカセットとは
レプリカセットとは複数のmongodbでデータの同期とサーバの冗長化を行う機能です。
MySQLのレプリケーションのようなものです。
MongoDB River Pluginを実行するために必要ですが、セカンダリを用意する必要はありません。
###etc/mongod.confを編集します。
sudo vi /etc/mongod.conf
replSet = rs01 # 最後に追記
###mongodbでレプリカセットを設定する
sudo service mongod restart
###mongodコンソールにて実行
mongo
config = {_id: 'rs01', members: [{_id: 0, host: 'localhost:27017'}]};
rs.initiate(config);
##mongodbにデータを作ってみる
ElasticSearchにインデックスを作成
curl -XPUT 'http://localhost:9200/_river/mongodb/_meta' -d '{
"type": "mongodb",
"mongodb": {
"db": "testmongo",
"collection": "animal"
},
"index": {
"name": "mongoindex",
"type": "animal"
}
}'
mongoでデータを作成
mongo
use testmongo
var p = {name:"キツネ"}
db.animal.save(p)
動作を確認する
検索する日本語をUTFからURLエンコードする必要があります。
以下のサイトで変換すると「キツネ」は %e3%82%ad%e3%83%84%e3%83%8d です。
日本語で検索してみる
curl -XGET 'http://localhost:9200/mongoindex/_search?q=name:%e3%82%ad%e3%83%84%e3%83%8d&pretty'
{
"took" : 3,
"timed_out" : false,
"_shards" : {
"total" : 5,
"successful" : 5,
"failed" : 0
},
"hits" : {
"total" : 1,
"max_score" : 0.30685282,
"hits" : [ {
"_index" : "mongoindex",
"_type" : "animal",
"_id" : "55116bc107a66baa7b209026",
"_score" : 0.30685282,
"_source":{"_id":"55116bc107a66baa7b209026","name":"キツネ"}
} ]
}
}
※見づらいので一番後ろにprettyパラメータを入れています。
##終わり
これでmongodbで日本語全文検索ができるようになりました。。。。お疲れ様です(´ω`;)
またすでにあるmongodbのデータから日本語で検索したい場合は、
ElasticSearchにインデックスを作成する際にdbとcollectionとtypeを合わせてください。
またElasticSearchのインデックスががよくわからないことになったときは
curl -XDELETE 'http://localhost:9200/*' で全部消せます。
##遭遇したエラー
バージョン無視して入れていたらエラーが発生しました。
Caused by: java.lang.ClassNotFoundException: org.elasticsearch.index.analysis.kuromojitokenizer.KuromojiTokenizerTokenizerFactory
at java.net.URLClassLoader$1.run(URLClassLoader.java:366)
at java.net.URLClassLoader$1.run(URLClassLoader.java:355)
at java.security.AccessController.doPrivileged(Native Method)
at java.net.URLClassLoader.findClass(URLClassLoader.java:354)
at java.lang.ClassLoader.loadClass(ClassLoader.java:425)
at sun.misc.Launcher$AppClassLoader.loadClass(Launcher.java:308)
at java.lang.ClassLoader.loadClass(ClassLoader.java:358)
at org.elasticsearch.common.settings.ImmutableSettings.loadClass(ImmutableSettings.java:469)
... 18 more
もうインデックスの削除コマンドすら受け付けないので、
以下のように手動でデータを消してしまいましょう。
sudo rm -r /var/lib/elasticsearch
mongodbで日本語検索が(略
mongodbでいつか日本語検索ができることを願っております(´ω`)b
##参考URL
http://cohakim.com/archives/5367
https://github.com/richardwilly98/elasticsearch-river-mongodb
https://github.com/elastic/elasticsearch-analysis-kuromoji
そういえばAmazon Elasticsearch Serviceが出ましたね。