Elasticsearch クイックスタート

Elasticsearch Quick Start — インストールからインデックス、検索までのクイックスタート手順


パッケージに含まれているREADMEを参考に、Elasticsearch のダウンロードからインデックス〜検索までの手順まとめ。

INSTALLATION.

download

Elasticsearch の最新バージョンをここから入手して、解凍。基本的にインストールはこれだけ、プロダクションのサーバーにセットアップするときは、apt や yum のリポジトリも用意されています。

$ tar zvxf elasticsearch-1.0.1.tar.gz

settings

Elasticsearch を起動するには、Java 6 以上が必要です。使用するJavaはJAVA_HOME 環境変数で設定します。

$ export JAVA_HOME=`/usr/libexec/java_home`

japanese (kuromoji) Analysis for Elasticsearch

日本語が検索できるように、kuromoji をインストールして設定します。ちなみに kuromojiのバージョン・各種設定の詳細はここで確認。

インストールは次のコマンドで簡単にインストールできます。

$ bin/plugin --install elasticsearch/elasticsearch-analysis-kuromoji/2.0.0

本来なら、インデックスデータの内容と検索要件をもとに、フィールド毎にkuromojiを使う設定をした方が良いかもしれませんが、ここでは kuromoji をデフォルトの Analysis として設定します。

$ vi config/elasticsearch.yml
index.analysis.analyzer.default.type: custom
index.analysis.analyzer.default.tokenizer: kuromoji_tokenizer

※ その他、便利なプラグインへ別途まとめる

run

Elasticsearch を起動するには、パッケージを解凍したディレクトリに移動して、次のコマンドを実行します。

$ bin/elasticsearch

バックグラウンドで起動する場合は、-d オプションをつけて実行します。

$ bin/elasticsearch -d

health

起動した Elasticsearch の状態を確認するには、次のコマンドを実行します。

$ curl ‘localhost:9200/_cat/health?v&ts=0'

結果は次のようにgreenと表示されればOKです。まだ Index 作成していないため、shards の数は0と表示されています。

epoch timestamp cluster status node.total node.data shards pri relo init unassign 
1394596688 12:58:08 elasticsearch green 1 1 0 0 0 0 0
デフォルトポート :
Elasticsearch で使用する HTTP用のデフォルトポートは、9200 (9200 〜 9300)。ノード間のコミュニケーション用に 9300 (9300 〜 9400)。使用するポートに範囲があるのは、既にポートが使用されている場合、自動的に次のポートを使う使用になっている為。例えば、同じサーバー内で、複数のElasticsearch を起動すれば、1つ目に起動したプロセスは 9200 ポートを使用し、次に起動したプロセスは 9201 ポートを使用します。

INDEXING.

README にならって、Twitter の情報をインデックス対象にします。インデックスを作成する際は、どんなデータをどうやってインデックス・検索するかを考慮して考ます。

ここでは、システム規模などは無視して単純に、Twitter Index と、その配下に user と tweet とという Type で構成します。

Index は、論理的なインデックスを構成するトップレベルのオブジェクトです。複数の Type を定義することができます。また、Type はフィールド構成やフィールドのデータをインデックスする際の解析処理などを管理しています。 RDB で例えるなら、テーブルに相当するオブジェクトです。

-- Index と Type 構成 --
Index: "twitter"
Type: "users"
Type: "tweets"
-- スキーマ構成 --
users:
id: ユーザーID
name: ユーザー名
tweets:
id: ユニークID
user: ユーザーID
post_date: 投稿日時
message: ツィートの内容

インデックスする

はじめに、”users” の情報を登録。次のコマンドで、”twitter” Index と “users” Type も自動的に作成されます。

$ curl -XPUT 'localhost:9200/twitter/users/taro' -d '
{
"name": "山田 太郎"
}'

つづいて、ツィート情報を登録します。

$ curl -XPUT 'localhost:9200/twitter/tweets/1' -d '
{
"user": "taro",
"post_date": "2014-03-11T12:28:00",
"message": "1つ目のツィート"
}'
$ curl -XPUT 'localhost:9200/twitter/tweets/2' -d '
{
"user": "taro",
"post_date": "2014-03-11T13:45:00",
"message": "2つ目のツィート"
}'

今回は、事前にフィールドの型などスキーマの定義をしていませんが、Elasticsearch が自動的に判断して定義されます。Elasticsearch の特徴の一つです。また、明示的に定義することもできます。

登録内容を確認する

登録した内容を確認するには、次のコマンドを実行します。

$ curl -XGET 'localhost:9200/twitter/users/taro?pretty=true'
$ curl -XGET 'localhost:9200/twitter/tweets/1?pretty=true'
$ curl -XGET 'localhost:9200/twitter/tweets/2?pretty=true'
Tips: pretty=true パラメータは、JSONの結果表示読みやすくする為に付与しています。YAML形式が好みなら、format=yaml パラメータをつけて実行します。

SEARCHING.

登録した、”taro” ユーザー全てのツィートを検索するには、次のコマンドを実行します。

テキスト検索

$ curl -XGET 'localhost:9200/twitter/tweets/_search?query=user:taro&pretty=true'

JSON Query Language を使って、次のように検索することもできます。

$ curl -XGET 'localhost:9200/twitter/tweets/_search?pretty=true' -d '
{
"query": {
"term": {"user": "taro"}
}
}'

検索条件無しに、全てのドキュメントを取得するには、次のコマンドを実行します。

$ curl -XGET 'localhost:9200/twitter/_search?pretty=true' -d '
{
"query" : {
"matchAll": {}
}
}'

範囲検索

日付フィールドを対象に、範囲検索するには次のコマンドを実行します。

$ curl -XGET 'localhost:9200/twitter/_search?pretty=true' -d '
{
"query": {
"range": {
"post_date": {
"from": "2014-03-11T13:00:00",
"to": "2014-03-11T14:00:00"
}
}
}
}'

MULTI TENANT.

Twitter の情報を検索できる実用的なシステムを想定した場合、Elasticsearch の分散処理システムをうまく活用できるように、上記のインデックス設計とは異なる設計が必要になる場合があります。

Elasticsearch は複数の Index と、各 Index 毎に複数の Type をサポートするため、以下のようなインデックス構成も可能です。

-- ユーザー毎のインデックス構成例 --
Index: "taro"
Type: "info"
Type: "tweets"
Index: "hanako"
Type: "info"
Type: "tweets"
...

なぜ、Index の設計が分散処理に関係があるかというと、物理的なインデックスを管理している Shard と深く関係します。先に設計したインデックス構成では、1つの Index が作成されます。物理的にはそのインデックスに対して(デフォルトでは)5つの Shard に分割され管理されます。各 Node (=サーバー) には、この分割された Shard 単位で分散される仕様のため、インデックス数・サイズ・更新速度の拡張では最大5台までとなるからです。

Shard 数は変更可能ですが、一度作成した Shard 数は変更できないため、事前にビックデータが予想される場合は、インデックス設計を考慮する必要があります。

今回の設計では、ユーザー単位で Index を作成するため、インデックスするデータの増加にあわせて柔軟にシステムを拡張することが可能と言えます。

また、ユーザー単位の設計にして、Shard 数を少なくしたい場合は、インデックスを作成する前に、次のコマンドで変更可能です。このコマンド例では、Primary Shard を1つとReplica Shard を一つ作成するように設定しています。

$ curl -XPUT 'localhost:9200/hanako/' -d '
{
"index": {
"numberOfShards": 1,
"numberOfReplicas": 1
}
}'

複数のインデックス横断検索する

複数の Index を横断で検索するには、次のコマンドを実行します。

-- 特定の複数のIndexを対象にする場合 --
$ curl -XGET 'localhost:9200/taro,hanako/_search?pretty=true' -d '
{
"query":{
"matchAll": {}
}
}'
-- 全てのIndexを対象に検索する場合 --
$ curl -XGET 'localhost:9200/_search?pretty=true' -d '
{
"query":{
"matchAll": {}
}
}'

分散処理システムのサーチエンジンにしては、かなりシンプルになっていると思う。ドキュメントの登録、検索、各種設定のコントロールが RESTful API で提供されているため、他のシステムとの連携やあるアプリケーションの一部として使うのに使いやすそうな印象。大規模なシステムは、Index の設計と、Shard 構成あたりが肝になりそう。