ElasticsearchのインストールとCSVからのデータ挿入

全文検索システムを Rails アプリケーションで利用するために、Elasticsearch を試してみます。Elasticsearch は Solr 同様、Apache Luceneベースですので、動作には Java 環境が必要です。今回は、Elasticsearch の入門編ということで、インストールとデータをCSVからインポートさせるところまで行います。

Elasticsearch.org Open Source Distributed Real Time Search & Analytics | Elasticsearch

スポンサーリンク

Elasticsearch については日本語の情報ページとしては、以下の記事が導入に大変参考になりました。

Elasticsearchチュートリアル – 不可視点
実践!Elasticsearch – Wantedly Engineer Blog
Kuromojiで日本語全文検索 – AWSで始めるElasticSearch(1) | Developers.IO

ありがとうございました。

Elasticsearch とプラグインのインストール、動作確認

まずは、Elasticsearch 本体をローカルの Mac 開発環境にインストール。homebrew で一発で入りました。

続いて便利そうなプラグインをいくつか入れてみます。

Plugins

/usr/local/bin/plugin コマンドを使用してプラグインをインストールします。私は /usr/local/bin に PATH を通しているので以下 plugin コマンドで進めます。

管理・モニター用のプラグインである marvel をインストール。

Marvel Documentation

クエリの管理とデバッグに便利そうな Inquisitor Plugin を入れる。

https://github.com/polyfractal/elasticsearch-inquisitor

web のフロントエンドである Elasticsearch Head Plugin を入れる。

https://github.com/mobz/elasticsearch-head

日本語の解析に必須である Kuromoji プラグインを入れる。

https://github.com/elasticsearch/elasticsearch-analysis-kuromoji

あとで CSV データのインポートを試してみるので、CSV River Plugin を入れる。

https://github.com/AgileWorksOrg/elasticsearch-river-csv

とりあえずプラグインはこのくらいで。

ここまで終わったら elasticsearch を起動。

http://127.0.0.1:9200/ にアクセスして “status”: 200 が返っていればOK。また、head プラグインをインストールした場合、http://127.0.0.1:9200/_plugin/head/ にアクセスして head のインターフェースが表示されることが確認できるはずです。

Elasticsearch に入れるデータをダウンロード

Elasticsearchチュートリアル – 不可視点 のページにならい、Livedoorグルメのデータを利用してみることにします。以下の作業は ~/work ディレクトリで行いました。

CSV がわらわらとディレクトリ直下にできちゃったので、フォルダにまとめました。

restaurants.csv を使おうと思います。データ構造を確認する。

1行目がヘッダーになっている。

Elasticsearch でスキーマ定義

restaurants.csv のデータを Elasticsearch に実際に入れる前に、Elasticsearch でのデータの取扱を定義するスキーマを作成します。

ここで、MySQL では出てこない N-gram, アナライザーなどの知識が必要になるので、知らない場合は以下の記事に目を通しておくと先に進めやすいです。

ビッグデータ処理の常識をJavaで身につける(1):検索エンジンの常識をApache Solrで身につける (1/4) – @IT

最初私は、N-gram、アナライザー、トークナイザー、転置インデックスって何それ?という状態だったのですが、この@ITの記事のおかげですんなりと概念を掴めました。Apache Solr のトピックではありますが、それらの必要な基礎知識は、Elasticsearch でも一緒です。

では、Elasticsearch のスキーマ定義に戻ります。

Elasticsearchチュートリアル – 不可視点 のページで Elasticsearch のデータ構造の図がとても分かりやすいです。MySQL でいうと、index が database に、type が table に相当します。

Elasticsearch のスキーマ定義では、mappings プロパティ以下で type で扱うプロパティ名(MySQLでいうカラム名)とそのデータ型、アナライザー(後述)を設定します。mappings は、MySQL でいう create table の際にカラム名とそのデータ型を指定するのに近い感じです。

もう一つ、Elasticsearch のスキーマ定義で大事なのが、analysis プロパティ以下で設定する filter(フィルター)、tokenizer(トークナイザー)、analyzer(アナライザー)の指定。filter はストップワードの指定、tokenizer は利用するトークナイザーを N-gram にするか形態素解析にするかの指定などを行い、analyzer は filter と tokenizer を組み合わせて独自のアナライザーを作成します。それぞれ、複数の filter, tokenizer, analyzer を定義することが可能です。

restaurants.csv を元に Elasticsearch のスキーマ定義

それでは restaurants.csv に戻って、それに対応する Elasticsearch のスキーマを定義します。analysis プロパティについては、実践!Elasticsearch – Wantedly Engineer Blog を参考にしつつ、mappings プロパティは restaurants.csv とにらめっこしながら作成。

今回は入門目的なので、親子関係の type は作成せず、restaurants.csv 単一の type を作成します。カラム名に相当するプロパティの type(データ型)には、integer, string を使いました。当初 geo_point, date も使っていたのですが、後述する CSV からデータをインデックスする際に例外が発生してエラーになりましたので。Elasticsearch で利用できるデータ型は以下で確認できます。

Core Types

作成した schema.json から index を作成します。index 名を ldgourmet とします。curl コマンドと REST API で操作できます。

認識 true となっているので上手く行ったみたいです。http://127.0.0.1:9200/_plugin/head/ にアクセスしてみますと、ldgourmet という index を確認できました。

CSV River Plugin で restaurants.csv データを Elasticsearch に入れる

さてとスキーマ定義を元に ldgourmet という名前の Elasticsearch の index を作成できたので、次はいよいよ restaurants.csv から ldgourmet の index へとデータを流し込みます(インデックスさせる)。冒頭のプラグインのインストールで入れた CSV River Plugin を利用します。

https://github.com/AgileWorksOrg/elasticsearch-river-csv

データをインデックスさせるための json ファイルを作成します。

concurrent_requests, bulk_size, bulk_threshold とかいまいち分からないのですけど、とりあえず Github の readme 通りの設定で。import_data.json を作成したら、ldgourmet の index にデータをインポートします。

ここで注意点がひとつあるのですが、この CSV River プラグインを使うコマンドを実行後は、利用した CSV ファイルが自動的に restaurants.csv → restaurants.csv.processing.imported とリネームされます。なので、やり直す場合などは、以下のように cp する。

それと、私の環境ではここで問題が発生しました。データは入ったのですが、Elasticsearch の head プラグイン(http://127.0.0.1:9200/_plugin/head/)で確認すると、データ中の日本語で文字化けが発生しました。文字化けなどが起こらなければ、以上の方法でOKです。

Mac の Java はデフォルト SJIS の文字コードらしいのですが、それが原因かなあ… Java のことよく分からないし原因特定も解決もできませんでしたので、私は結局以降に説明する代替手段でデータをインポートしました。

Elasticsearch の index api を使ってデータを入れる

Index API

上記のAPIを使って試しにデータを何件か入れてみたところ、日本語の文字化けが発生せず正常にデータが入ることを確認できたので、以下の ruby スクリプトを書きました。

insert_data.rb

パーミッション変更。

データのインポートを実行。

restaurants.csv は20万件以上のレコードなので、データを全部入れ終わるのにしばらく時間がかかります。

以上で無事にデータが Elasticsearch に入りました。とりあえず今日はここまで、次回に Elasticsearch のクエリを使って検索を試した記事を書きます。

スポンサーリンク
全文検索システムを実装するには、ElasticSearch がおすすめです。
スポンサーリンク
 
Twitterを使っていますのでフォローお願いたします!ブログの更新情報もつぶやいてます^^
(英語学習用)

Leave Your Message!