mongodbから日本語で全文検索するためにElasticSearchをインストールする

##mongodb での全文検索
mongodbで日本語で全文検索したい！と思ってもこれが残念ながら未だ非対応です。※2015年10月
[参考URL](http://docs.mongodb.org/manual/reference/text-search-languages/#text-search-languages)  
そこでElasticSearch プラグイン(MongoDB River + Kuromoji Analysis)を利用します。
ElasticSearchからプラグインを色々使ってmongodbから全文検索する感じです。

そのためにいろいろとハマったのでメモ的に書いていきます。
必要なものは以下です。

* mongodb
* JDK (Java Development Kit)
* [ElasticSearch](https://www.elastic.co/)
* [MongoDB River Plugin (プラグイン)](https://github.com/richardwilly98/elasticsearch-river-mongodb)(mongodbの接続用)
* [Kuromoji Analysis Plugin (プラグイン)](https://github.com/elastic/elasticsearch-analysis-kuromoji)(日本語形態素解析)

環境は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あたりだと思うのでそのつもりで各自選択していきます。

####今回利用するバージョン
<table><tr><th>mongodb</th><th>ElasticSearch</th><th>Kuromoji Analysis Plugin</th><th>MongoDB River Plugin</th></tr><tr><td>2.6.8</td><td>1.3.9</td><td>2.3.0</td><td>2.0.2</td></tr></table>

バージョン気にせずインストールをするとなぜか動かなかったりしますのでご注意ください。
マイナーバージョンの違いくらいだったらなんとかなるのかもしれませんが、保証はありません。
無視してやるのもいいですが、その場合は出来る限り下のバージョンにした方がいいです。
~~しかし、何度も言いますが、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 です。

[URLエンコード・デコードフォーム](http://www.tagindex.com/tool/url.html)

### 日本語で検索してみる
```
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でいつか日本語検索ができることを願っております(´ω`)ｂ

##参考URL
http://cohakim.com/archives/5367
https://github.com/richardwilly98/elasticsearch-river-mongodb
https://github.com/elastic/elasticsearch-analysis-kuromoji

そういえばAmazon Elasticsearch Serviceが出ましたね。