ラベル ElasticSearch の投稿を表示しています。 すべての投稿を表示
ラベル ElasticSearch の投稿を表示しています。 すべての投稿を表示

2016年3月28日月曜日

【Rails Elasticsearch】unexpected token at {json}

記事概要

Railsでelasticsearchを利用した時に発生したエラーの修正方法をまとめた記事です

環境

  • centos6.5
  • rails4.2.5
  • ruby2.3.0
  • rbenv
  • elasticsearch2.2.0

railsとelasticsearchの連携

elasticsearchには、railsで利用するための公式のgemが用意されています。

上記のgemを利用したところ、検索メソッド(search)を呼び出した時に

unexpected token at

エラーが発生しました。

このエラーは、rubyでjsonのパースに失敗した時に発生するエラーです。なので、すぐに修正できると思っていましたが、推測がことごとく外れ、エラーにはまってしまいました。結局、理解にほぼ丸一日を費やしてしまいました。

エラーの原因

elasticsearchのデータ投入をする際に、elasticsearch-railsライブラリではなく、elasticsearchのbulk APIでコマンドラインからデータを投入したのが原因でした。利用したコマンドは以下です。

terminal

curl -XPOST 'localhost:9200/{index_name}/{type_name}/_bulk?pretty' --data-binary "@data.json"

上記のコマンドでデータを投入すると、elasticsearch-railsで実装されているメソッドを使ってデータを取得する際に、unexpected token atが発生します。
しかし、コマンドからelasticsearchのAPIを叩く場合は、正常に動作します。

terminal

// エラーが発生せずに、うまくいく
curl -XGET 'http://localhost:9200/{index_name}/{type_name}/1'

また、railsから呼び出す場合でも、取得データ件数が0件の場合は正常に動作します。

{project_folder}/app/controllers/elastic_controller.rb

client = Elasticsearch::Client.new log: true

// 結果がo件ならエラーが発生しない。
response = client.search index: '{index-name}', type: '{type-name}', q: 'tags:tagname'
response.map {|data|
  p logger.debug data
}

このため、エラーの原因調査に時間がかかりました。

エラーパターン

elasticsearch-railsとelasticsearchの連携でエラーが発生するパターンを以下にまとめました。

データの投入方法 検索方法 結果
bulk api railsからsearchメソッド呼び出し × railsでunexpected token atエラー発生
bulk api コマンドから {index}/{type}/_searchAPI呼び出し ○ コマンドラインに結果が出力される
rails api railsからsearchメソッド呼び出し
rails api コマンドから {index}/{type}/_searchAPI呼び出し ○ コマンドラインに結果が出力される

エラー修正方法

上記のエラーパターンより、rails apiを利用してデータを投入すればよいことがわかります。
railsからのデータの投入方法は以下のようになります。

{project_folder}/app/controllers/elastic_controller.rb

client = Elasticsearch::Client.new log: true
client.create index: '{index-name}', type: '{type-name}', id: 1, body: { tags: 'tagname' }

createメソッドを呼ぶことでコード側からデータを投入できます。
railsコンソールを使ってデータを投入しても同じです
なので、本番にデータ投入の際は、railsコンソールを利用することになります。

検索実装

上記のようにrailsを介してElasticsearchのindexとtypeにデータを登録したら、railsから検索可能なことを確かめてみましょう。

{project_folder}/app/controllers/elastic_controller.rb

client = Elasticsearch::Client.new log: true

// 結果を取得してもエラーが発生しない。
response = client.search index: '{index-name}', type: '{type-name}', q: 'tags:tagname'
response.map {|data|
  p logger.debug data
}

うまく検索できるはずです。

まとめ

railsでElasticsearchを使い、elasticsearch-railsのgemを利用する場合は、railsコンソールからelasticsearch-railsを使ってデータのメンテナンスをしましょう。
railsをうまく使うには規約に従うことが重要です。自分なりのスタイルに変更するのは、慣れてきてからにしましょう。

以上。

PICK UP オススメ書籍

運営サイト(railsで作成しています)


この記事がお役にたちましたらシェアをお願いします

このエントリーをはてなブックマークに追加

2016年1月13日水曜日

elasticsearch 作成済みのindexにanalyzerを設定する

  • 公開日:2016年01月13日

記事概要


elasticsearchで作成済みのindexにanalyzerを設定する方法を記載した記事です。

環境


  • vagrant centos6.5
  • elasticsearch2.1.1
  • java(OpenJDK) version 1.7.0_91

indexの作成


elasticsearchでindexを作成する場合は、以下のように実行します。

terminal

// command
curl -XPUT 'localhost:9200/sample_ana?pretty'

// result
{
  "acknowledged" : true
}

settingを確認します。

terminal

// command
curl -XGET 'http://localhost:9200/sample_ana/_settings'

// result
{
 "sample_ana": {
  "settings": {
   "index": {
    "creation_date": "1452649163895",
    "uuid": "fCWnTlE_SZ2OiWC796SBBA",
    "number_of_replicas": "1",
    "number_of_shards": "5",
    "version": {
     "created": "2010199"
    }
   }
  }
 }
}

indexが作成されていますね。

indexにanalyzerを定義


上記のindexにはanalyzerが設定されていません。なので、analyzerの設定を行います。

terminal

// command
curl -XPOST 'localhost:9200/sample_ana/_close'

// result
{
 "acknowledged": true
}

まずはclose index APIでindexの_closeを実行する必要があります。
close index APIは、indexをクローズすることができます。また、その後、open index APIでindexをopenにすることもできます。 この処理を実行しないとindex定義後にanalyzerは定義できないので注意してください。

では、状態を確認してみましょう。

terminal

// command
curl 'localhost:9200/_cat/indices?v'

// result
health status index      pri rep docs.count docs.deleted store.size pri.store.size
       close  sample_ana

index sample_anaがcloseの状態になっています。

次にanalyzerの設定を行います。tokenizerにはkuromojiを使います。
kuromojiに関しては、以前にも記事にしているので、kuromojiについて理解したい人は参考にしてみてください。

terminal

// command
curl -XPUT 'localhost:9200/sample_ana/_settings' -d '
{
      "analysis": {
        "tokenizer": {
          "kuromoji_user_dict": {
            "type": "kuromoji_tokenizer",
            "mode": "extended",
            "discard_punctuation": "false",
            "user_dictionary": "userdict_ja.txt"
          }
        },
        "analyzer": {
          "my_analyzer": {
            "type": "custom",
            "tokenizer": "kuromoji_user_dict"
          }
        }
      }
}'

// result
{
 "acknowledged": true
}

うまくいったようです。
open index APIでindexをopenにします。

terminal

// command
curl -XPOST 'localhost:9200/sample_ana/_open'

// result
{
 "acknowledged": true
}

状態を確認します。

terminal

// command
curl 'localhost:9200/_cat/indices?v'

// result
health status index      pri rep docs.count docs.deleted store.size pri.store.size
yellow open   sample_ana   5   1          0            0       650b           650b

動作しています。
最後に設定を確認します。

terminal

// command
curl -XGET 'http://localhost:9200/sample_ana/_settings'

// result
{
 "sample_ana": {
  "settings": {
   "index": {
    "creation_date": "1452649163895",
    "uuid": "fCWnTlE_SZ2OiWC796SBBA",
    "analysis": {
     "analyzer": {
      "my_analyzer": {
       "type": "custom",
       "tokenizer": "kuromoji_user_dict"
      }
     },
     "tokenizer": {
      "kuromoji_user_dict": {
       "user_dictionary": "userdict_ja.txt",
       "type": "kuromoji_tokenizer",
       "discard_punctuation": "false",
       "mode": "extended"
      }
     }
    },
    "number_of_replicas": "1",
    "number_of_shards": "5",
    "version": {
     "created": "2010199"
    }
   }
  }
 }
}

ちゃんとanalyzerにkuromojiが設定されました。

まとめ


elasticsearchで作成済みのindexにあれこれと再設定をするときは、Open / Close Index APIを利用するのがコツです。
elasticsearchはあまり日本語の情報がありませんが、テスト環境を構築してコツコツといじっていくのが使いこなしていく近道です。

以上です。

ElasticSearchの開発にオススメの本


オススメ開発マシン


関連記事


参考サイト


この記事がお役にたちましたらシェアをお願いします

このエントリーをはてなブックマークに追加

2016年1月7日木曜日

elasticsearch plugin installの失敗 SSLException java.security.ProviderException

  • 公開日:2016年01月07日

記事概要


elasticsearchでpluginコマンドを実行したところ、SSLException java.security.ProviderExceptionが発生してインストールに失敗しました。
その対応方法をまとめた記事です。
read in English

環境


  • vagrant centos6.5
  • elasticsearch2.1.1
  • java(OpenJDK) version 1.7.0_91

kurimoji plugijn installの失敗


kurimoji(Javaで書かれた日本語形態素解析ソフトウェア)はelasticsearch2.1以降では、pluginに公式に取り込まれています。
なので、以下のようにinstallができます。

terminal

sudo /usr/share/elasticsearch/bin/plugin install --verbose analysis-kuromoji

Failed: SSLException[java.security.ProviderException: java.security.KeyException]; nested: ProviderException[java.security.KeyException]; nested: KeyException;
ERROR: failed to download out of all possible locations

しかし、私の環境では、pluginコマンドは上記のように失敗しました。

javaのvesionの切り替え


結論から述べるとpluginのinstallに失敗するのは、javaのversionが原因です。
なのでinstallされているjavaをチェックします。

terminal

yum search java | grep openjdk
java-1.6.0-openjdk.x86_64 : OpenJDK Runtime Environment
java-1.6.0-openjdk-demo.x86_64 : OpenJDK Demos
java-1.6.0-openjdk-devel.x86_64 : OpenJDK Development Environment
java-1.6.0-openjdk-javadoc.x86_64 : OpenJDK API Documentation
java-1.6.0-openjdk-src.x86_64 : OpenJDK Source Bundle
java-1.7.0-openjdk.x86_64 : OpenJDK Runtime Environment
java-1.7.0-openjdk-demo.x86_64 : OpenJDK Demos
java-1.7.0-openjdk-devel.x86_64 : OpenJDK Development Environment
java-1.7.0-openjdk-javadoc.noarch : OpenJDK API Documentation
java-1.7.0-openjdk-src.x86_64 : OpenJDK Source Bundle
java-1.8.0-openjdk.x86_64 : OpenJDK Runtime Environment
java-1.8.0-openjdk-debug.x86_64 : OpenJDK Runtime Environment with full debug on
java-1.8.0-openjdk-demo.x86_64 : OpenJDK Demos
java-1.8.0-openjdk-demo-debug.x86_64 : OpenJDK Demos with full debug on
java-1.8.0-openjdk-devel.x86_64 : OpenJDK Development Environment
java-1.8.0-openjdk-devel-debug.x86_64 : OpenJDK Development Environment with
java-1.8.0-openjdk-headless.x86_64 : OpenJDK Runtime Environment
java-1.8.0-openjdk-headless-debug.x86_64 : OpenJDK Runtime Environment with full
java-1.8.0-openjdk-javadoc.noarch : OpenJDK API Documentation
java-1.8.0-openjdk-javadoc-debug.noarch : OpenJDK API Documentation for packages
java-1.8.0-openjdk-src.x86_64 : OpenJDK Source Bundle
java-1.8.0-openjdk-src-debug.x86_64 : OpenJDK Source Bundle for packages with

yumには最新のjava-1.8.0-openjdkが存在しています。
次に、現在利用しているjavaを確認します。

terminal

alternatives --config java

There are 2 programs which provide 'java'.

  Selection    Command
-----------------------------------------------
   1           /usr/lib/jvm/jre-1.5.0-gcj/bin/java
*+ 2           /usr/lib/jvm/jre-1.7.0-openjdk.x86_64/bin/java


java-1.8.0-openjdkがinstallされていません。
なので、installします。

terminal

sudo yum install -y java-1.8.0-openjdk

javaのversionをチェックします。

terminal

java -version
java version "1.7.0_91"

利用しているjavaが変更されていないので切り替えます。

terminal

sudo alternatives --config java

There are 3 programs which provide 'java'.

  Selection    Command
-----------------------------------------------
   1           /usr/lib/jvm/jre-1.5.0-gcj/bin/java
*+ 2           /usr/lib/jvm/jre-1.7.0-openjdk.x86_64/bin/java
   3           /usr/lib/jvm/jre-1.8.0-openjdk.x86_64/bin/java

Enter to keep the current selection[+], or type selection number: 3

再度versionをチェックします。

terminal

java -version
openjdk version "1.8.0_65"
OpenJDK Runtime Environment (build 1.8.0_65-b17)
OpenJDK 64-Bit Server VM (build 25.65-b01, mixed mode)

java-1.8.0-openjdkに変更されました。

kurimoji plugin の再install


java-1.8.0-openjdkになったので、再度pluginコマンドを実行します。

terminal

sudo /usr/share/elasticsearch/bin/plugin install --verbose analysis-kuromoji

Downloading .DONE
- Plugin information:
Name: analysis-kuromoji
Description: The Japanese (kuromoji) Analysis plugin integrates Lucene kuromoji analysis module into elasticsearch.
Site: false
Version: 2.1.1
JVM: true
 * Classname: org.elasticsearch.plugin.analysis.kuromoji.AnalysisKuromojiPlugin
 * Isolated: true
Installed analysis-kuromoji into /usr/share/elasticsearch/plugins/analysis-kuromoji

うまくいきました。
念のために、pluginを確認してみましょう。

terminal

sudo /usr/share/elasticsearch/bin/plugin list
Installed plugins in /usr/share/elasticsearch/plugins:
    - analysis-kuromoji

java7を使い続けたい人もいると思います。7に再度切り替えて確認してみましょう。

terminal

sudo alternatives --config java

There are 3 programs which provide 'java'.

  Selection    Command
-----------------------------------------------
   1           /usr/lib/jvm/jre-1.5.0-gcj/bin/java
*  2           /usr/lib/jvm/jre-1.7.0-openjdk.x86_64/bin/java
 + 3           /usr/lib/jvm/jre-1.8.0-openjdk.x86_64/bin/java

Enter to keep the current selection[+], or type selection number: 2

java -version
java version "1.7.0_91"
OpenJDK Runtime Environment (rhel-2.6.2.2.el6_7-x86_64 u91-b00)
OpenJDK 64-Bit Server VM (build 24.91-b01, mixed mode)

sudo /usr/share/elasticsearch/bin/plugin list
Installed plugins in /usr/share/elasticsearch/plugins:
    - analysis-kuromoji

問題ありませんね。

まとめ


elasticsearch2.1.1でpluginコマンドを利用する場合は、javaのversionを8にあげる必要があります。
pluginコマンドでjava8が必要なだけなので、plugin導入後はjava7で動いているシステムでも問題なく利用できます。

でも可能な限り最新版を利用するべきです。やはりアップデートはマメにやらないといけませんね。

以上。

オススメ開発マシン


関連記事


参考サイト


English


この記事がお役にたちましたらシェアをお願いします

このエントリーをはてなブックマークに追加

2015年12月24日木曜日

モダンエンジニアの基礎 検索エンジンを理解する 手を動かしてN-gram方式を学ぶ

  • 公開日:2015年12月24日

記事概要


新米エンジニアの学習用に作った資料です。未だに10年以上も前の研修項目をこなしている新入社員が多いこと多いこと。まあ、会社の教育システムが時代に合っていないのが悪いのですけどね。
そんなわけで、今後(2015年以降)WEB(スマホ)エンジニアとして働くなら知っておいて欲しい事柄をまとめてみました。
この記事では検索エンジンで使うN-gram方式をまとめました。

環境

  • elasticsearch2.1.1

N-gram方式とは


文章を文字列の並び順にN文字を見出し語としてインデックスする方法です。
Nは、切り出す文字の単位になります。
日本語や中国語など、言語に依存しない見出し語作成が可能な方式とされています。 検索漏れを少なくする特徴をもっています。

N-gramを用いるケース


例としては、検索漏れを少なくしたい店舗の名称、地域名などはN-gram方式でインデックスすると良いとされています。

N-gramのサンプル


  • ユニグラム = unigram (1文字単位)
  • バイグラム = bigram (2文字単位)
  • トリグラム = trigram (3文字単位)

のどれかを使うのが現実的とされています。
ここでは、bigram (2文字単位)を例にしてみましょう。

例1

東京都の天気は晴れです → 東京/京都/都の/の天/天気/気は/は晴/晴れ/れで/です

2文字で区切っているだけです。
なので、インデックス(索引)は以下の通りになります。

  • 東京
  • 京都
  • 都の
  • の天
  • 天気
  • 気は
  • は晴
  • 晴れ
  • れで
  • です

2文字で区切っていますね。確認にもう一つ例文を確認してみましょう。

例2

天気予報は晴れです → 天気/気予/予報/報は/は晴/晴れ/れで/です

  • 天気
  • 気予
  • 予報
  • 報は
  • は晴
  • 晴れ
  • れで
  • です

理解できましたね。それでは実際に検索エンジンのelasticsearchを使ってみましょう。

elasticsearchのインストール


では、実際にelasticsearchとrubyを利用して試して、理解を深めていきましょう。
環境はdockerやvagrantを使って用意することをお勧めします。
以下は、vagrantのcentos6.5を使ったinstall方法です。

terminal

// javaのinstall
sudo yum -y install java-1.7.0-openjdk

java -version
java version "1.7.0_91"
OpenJDK Runtime Environment (rhel-2.6.2.2.el6_7-x86_64 u91-b00)
OpenJDK 64-Bit Server VM (build 24.91-b01, mixed mode)

// rpm版を DLしてinstall
sudo rpm -ivh https://download.elasticsearch.org/elasticsearch/release/org/elasticsearch/distribution/rpm/elasticsearch/2.1.1/elasticsearch-2.1.1.rpm

### NOT starting on installation, please execute the following statements to configure elasticsearch service to start automatically using chkconfig
 sudo chkconfig --add elasticsearch
### You can start elasticsearch service by executing
 sudo service elasticsearch start
 
// chkconfigに追加
sudo chkconfig --add elasticsearch
// 確認
sudo chkconfig --list elasticsearch
elasticsearch   0:off   1:off   2:on    3:on    4:on    5:on    6:off

// 起動
sudo service elasticsearch start
Starting elasticsearch:                                    [  OK  ]

動作を確認します。

terminal

curl http://localhost:9200
{
  "name" : "Orb",
  "cluster_name" : "elasticsearch",
  "version" : {
    "number" : "2.1.1",
    "build_hash" : "40e2c53a6b6c2972b3d13846e450e66f4375bd71",
    "build_timestamp" : "2015-12-15T13:05:55Z",
    "build_snapshot" : false,
    "lucene_version" : "5.3.1"
  },
  "tagline" : "You Know, for Search"
}

以上でinstallは完了です。

N-gramの設定


elasticsearchでngramを使うには、Analyzersのトークナイザーにngramを設定します。

terminal

curl -XPUT 'http://localhost:9200/sample' -d '
    {
        "settings" : {
            "analysis" : {
                "analyzer" : {
                    "default" : {
                        "tokenizer" : "my_ngram_tokenizer"
                    }
                },
                "tokenizer" : {
                    "my_ngram_tokenizer" : {
                        "type" : "nGram",
                        "min_gram" : "2",
                        "max_gram" : "2",
                        "token_chars": [ "letter", "digit" ]
                    }
                }
            }
        }
    }'

サンプルなので、defaultのtokenizerをmy_ngram_tokenizerにしています。
type:nGramがngramの設定になります。
{"acknowledged":true}というjsonが返却されれば成功です。

N-gram解析を実行する


例文「東京都の天気は晴れです」をngramで解析します。

terminal

curl 'http://localhost:9200/sample/_analyze?pretty' -d '東京都の天気は晴れです'
{
  "tokens" : [ {
    "token" : "東京",
    "start_offset" : 0,
    "end_offset" : 2,
    "type" : "word",
    "position" : 0
  }, {
    "token" : "京都",
    "start_offset" : 1,
    "end_offset" : 3,
    "type" : "word",
    "position" : 1
  }, {
    "token" : "都の",
    "start_offset" : 2,
    "end_offset" : 4,
    "type" : "word",
    "position" : 2
  }, {
    "token" : "の天",
    "start_offset" : 3,
    "end_offset" : 5,
    "type" : "word",
    "position" : 3
  }, {
    "token" : "天気",
    "start_offset" : 4,
    "end_offset" : 6,
    "type" : "word",
    "position" : 4
  }, {
    "token" : "気は",
    "start_offset" : 5,
    "end_offset" : 7,
    "type" : "word",
    "position" : 5
  }, {
    "token" : "は晴",
    "start_offset" : 6,
    "end_offset" : 8,
    "type" : "word",
    "position" : 6
  }, {
    "token" : "晴れ",
    "start_offset" : 7,
    "end_offset" : 9,
    "type" : "word",
    "position" : 7
  }, {
    "token" : "れで",
    "start_offset" : 8,
    "end_offset" : 10,
    "type" : "word",
    "position" : 8
  }, {
    "token" : "です",
    "start_offset" : 9,
    "end_offset" : 11,
    "type" : "word",
    "position" : 9
  } ]
}

おお。2文字でうまく解析されていますね。もう一つの例文も試してみましょう。

terminal

curl 'http://localhost:9200/sample/_analyze?pretty' -d '天気予報は晴れです'
{
  "tokens" : [ {
    "token" : "天気",
    "start_offset" : 0,
    "end_offset" : 2,
    "type" : "word",
    "position" : 0
  }, {
    "token" : "気予",
    "start_offset" : 1,
    "end_offset" : 3,
    "type" : "word",
    "position" : 1
  }, {
    "token" : "予報",
    "start_offset" : 2,
    "end_offset" : 4,
    "type" : "word",
    "position" : 2
  }, {
    "token" : "報は",
    "start_offset" : 3,
    "end_offset" : 5,
    "type" : "word",
    "position" : 3
  }, {
    "token" : "は晴",
    "start_offset" : 4,
    "end_offset" : 6,
    "type" : "word",
    "position" : 4
  }, {
    "token" : "晴れ",
    "start_offset" : 5,
    "end_offset" : 7,
    "type" : "word",
    "position" : 5
  }, {
    "token" : "れで",
    "start_offset" : 6,
    "end_offset" : 8,
    "type" : "word",
    "position" : 6
  }, {
    "token" : "です",
    "start_offset" : 7,
    "end_offset" : 9,
    "type" : "word",
    "position" : 7
  } ]
}

きちんとN-gram(2-gram)で解析されていますね。

まとめ


最近のwebサイトには、当たり前のように検索エンジンが使われるようになっています。
一度理解してしまえば、DBのlike検索なんかよりはるかに優れた検索機能を持たせることができるので、是非習得してください。
elasticsearchもsolrも無料で利用可能です。

以上。

elasticsearchを理解するのにオススメの本


オススメ開発マシン


参考サイト

この記事がお役にたちましたらシェアをお願いします

このエントリーをはてなブックマークに追加

2015年6月15日月曜日

elasticsearchのデータ登録方法

記事概要


elasticsearchのデータ登録方法のまとめ

環境

  • vagrant centOS6.5
  • elasticsearch 1.5.2

Bulk API


elasticsearchでデータを大量に登録する場合は、Bulk APIを利用すると効率的です。
jsonファイルを用意し、以下のようにjsonを記述します。


 { "index": { "_index": "kuromoji_sample", "_type": "mountain", "_id": "1" }  }{ "id": "1", "name": "富士山",   "name_kana": "フジサン", "summary": "日本一の山だよ" }{ "index": { "_index": "kuromoji_sample", "_type": "mountain", "_id": "2" } }{ "id": "2", "name": "高尾山",    "name_kana": "タカオサン", "summary": "世界一登山客が多い山だよ。" }

このjsonを記載したファイルを『bulk.json』と名前をつけてデータ投入してみましょう。


#curl -XPOST http://localhost:9200/_bulk --data-binary @bulk.json >/dev/null

{"error":"JsonParseException[Unexpected end-of-input: expected close marker for OBJECT (from [Source: [B@664a3a13; line: 1, column: 0])\n at [Source: [B@664a3a13; line: 1, column: 4]]","status":500}

上記のエラーが発生しました。調べると、jsonに記述する形式は以下のようにする必要があるようです。


{インデックス},
{データ},
{インデックス},
{データ}

jsonファイルではなく、jsonでデータを記載したファイルです。
インデックスとデータを改行で分離する必要があります。

ファイルを修正してもう一度コマンドを叩きます。


curl -XPOST http://localhost:9200/_bulk --data-binary @bulk.json >/dev/null

  % Total    % Received % Xferd  Average Speed   Time    Time     Time  Current
                                 Dload  Upload   Total   Spent    Left  Speed
100  123k  100 10960  100  113k   5071  53640  0:00:02  0:00:02 --:--:-- 53744

エラーなく上手くいきました。

登録したサンプルデータを検索


inquisitorを利用します。
urlに『http://localhost:9200/_plugin/inquisitor/#/』を入力してelasticsearch-inquisitorを立ち上げます。


{
  "query": {
    "query_string": {
      "query": "富士"
    }
  }
}

Elapsed Time: 15ms Total Hits: 2 Max Score: 1

上手く登録できているのが確認できました。
上記の例はクエリー検索です。
inquisitorを利用すると、GUIで色々な検索パターンを試せます。
検索方法についてはまた別記事でまとめて説明します。

登録したサンプルデータを全て削除


curl -XDELETE 'http://localhost:9200/*'
{"acknowledged":true}

本番環境で使ってはいけないコマンドです。
一応載せておきます。

以上。

参考サイト


elasticsearch オススメ書籍


elasticsearchをがっつりと使うなら側においておきたい一冊です。
というより、日本語の本はこれしかありません。

この記事がお役にたちましたらシェアをお願いします

このエントリーをはてなブックマークに追加

2015年6月4日木曜日

elasticsearch Mapping

  • 公開日:2015年06月04日
  • 最終更新日:2015年06月06日

elasticsearchのmappingの学習メモ

環境

  • vagrant centOS6.5
  • elasticsearch 1.5.2

Mappingとは


リレーショナルDBでいうところのテーブル定義に相当します。
ただし、データを格納する為のフィールドを用意して、型を設定するだけのリレーショナルDBとは異なります。
elasticsearchではフィールドの型の他に、言語解析処理などのドキュメントを検索可能にする為の各種設定をすることができます。

Mappingの例


mappingの例を以下に記載します。


  "mappings": {
    "mountain": {
      "_source": {
        "enabled": true
      },
      "_all": {
        "enabled": true,
        "analyzer": "my_analyzer"
      },
      "properties": {
        "id": {
          "type": "integer",
          "index": "not_analyzed"
        },
        "name": {
          "type": "string",
          "index": "analyzed",
          "analyzer": "my_analyzer"
        },
        "name_kana": {
          "type": "string",
          "index": "analyzed",
          "analyzer": "my_analyzer"
        },
        "summary": {
          "type": "string",
          "index": "analyzed",
          "analyzer": "my_analyzer"
        }
      }
    }
  }

データの説明

  • id - integer型, 分割しない。つまり10を1とか0でヒットさせない。
  • 他 - String型。日本語が入り、『富士山』などの単位でヒットさせる。

サンプルなのでシンプルに作成してあります。フィールドに言語解析処理が色々と設定しているのが特徴です。
上記で設定しているanalyzerの『my_analyzer』はこの記事で作成したデータを利用しています。

Mappingの登録


上記のmappingを参考にし、index『kuromoji_sample』、type『mountain』のMappingデータを登録してみましょう。


curl -XPUT 'http://localhost:9200/kuromoji_sample/' -d'
{
    "settings": {
        "index":{
            "analysis":{
                "tokenizer" : {
                    "kuromoji_user_dict" : {
                       "type" : "kuromoji_tokenizer",
                       "mode" : "extended",
                       "discard_punctuation" : "false",
                       "user_dictionary" : "userdict_ja.txt"
                    }
                },
                "analyzer" : {
                    "my_analyzer" : {
                        "type" : "custom",
                        "tokenizer" : "kuromoji_user_dict"
                    }
                }

            }
        }
    },  
    "mappings": {
      "mountain": {
        "_source": {
          "enabled": true
        },
        "_all": {
          "enabled": true,
          "analyzer": "my_analyzer"
        },
        "properties": {
          "id": {
            "type": "integer",
            "index": "not_analyzed"
          },
          "name": {
            "type": "string",
            "index": "analyzed",
            "analyzer": "my_analyzer"
          },
          "name_kana": {
            "type": "string",
            "index": "analyzed",
            "analyzer": "my_analyzer"
          },
          "summary": {
            "type": "string",
            "index": "analyzed",
            "analyzer": "my_analyzer"
          }
        }
      }
    }
}
'

{"acknowledged":true}

{"acknowledged":true}が出力されれば登録は成功です。

Mappingの確認


mappingを確認にするために、
『http://localhost:9200/kuromoji_sample/_mapping/mountain?pretty=true』
にアクセスします。
urlの『_mapping/mountain』がポイントです。
pretty=trueはjsonを整形して表示したい場合に利用する引数です。


{
  "kuromoji_sample" : {
    "mappings" : {
      "mountain" : {
        "_all" : {
          "enabled" : true,
          "analyzer" : "my_analyzer"
        },
        "properties" : {
          "id" : {
            "type" : "integer"
          },
          "name" : {
            "type" : "string",
            "analyzer" : "my_analyzer"
          },
          "name_kana" : {
            "type" : "string",
            "analyzer" : "my_analyzer"
          },
          "summary" : {
            "type" : "string",
            "analyzer" : "my_analyzer"
          }
        }
      }
    }
  }
}

きちんと登録されています。


サンプルデータの登録


curl -XPOST 'http://localhost:9200/kuromoji_sample/mountain/_bulk' -d \
'
 { "index": { "_index": "kuromoji_sample", "_type": "mountain", "_id": "1" }  }
 { "id": "1", "name": "富士山",   "name_kana": "フジサン", "summary": "日本一の山だよ" }
 { "index": { "_index": "kuromoji_sample", "_type": "mountain", "_id": "2" } }
 { "id": "2", "name": "高尾山",    "name_kana": "タカオサン", "summary": "世界一登山客が多い山だよ。" }
'

大量のデータを投入する場合は、jsonファイルを使うと便利です。

登録したサンプルデータを検索


inquisitorを利用します。
urlに『http://localhost:9200/_plugin/inquisitor/#/』を入力してelasticsearch-inquisitorを立ち上げます。


{
  "query": {
    "query_string": {
      "query": "富士"
    }
  }
}

上記の例はクエリー検索です。
このように、ここで色々な検索パターンを試せます。
検索方法についてはまた別記事でまとめて説明します。

以上。

参考サイト


elasticsearch オススメ書籍


elasticsearchをがっつりと使うなら側においておきたい一冊です。
というより、日本語の本はこれしかありません。

この記事がお役にたちましたらシェアをお願いします

このエントリーをはてなブックマークに追加

2015年6月1日月曜日

elasticsearch Kuromoji

elasticsearchにKuromojiを導入したので、学習メモ

環境

  • vagrant(centOS6.5)

Kuromojiとは

Javaで書かれているオープンソースの日本語形態素解析エンジンです。
メールサーバーを構築したことがある人は、Mecabをイメージするとよいと思います。
solrを利用したことがある人は、solrのkuromojiと全く同じなので学習の必要はありません。

インストール

こちらの記事に手順を記載しています。chefで導入しています。

サンプルの作成

まずは簡単なサンプルを作成していきましょう。ここではindex名『kuromoji_sample』でデータを作成します。
indexってなにそれ?の場合は、この記事で基礎から学習してください。

user_dictionaryを作成

まずはユーザ辞書を作成します。

ファイル名『userdict_ja.txt』を作成します。
ファイルの保存先は『/usr/local/etc/elasticsearch』になります。
公式サイトの説明だと{home}/config配下と記載されていますが、間違いです。(少なくともcentosの場合は)


// elasticsearch homeへ移動
cd /usr/local/etc/elasticsearch

sudo touch userdict_ja.txt

chmod 777 elasticsearch:elasticsearch userdict_ja.txt

userdict_ja.txtを作成します。文字コードはutf-8です。


富士,富士,フジ,カスタム名詞
高尾,高尾,タカオ,カスタム名詞

elasticsearchを再起動します。


sudo service elasticsearch restart

インデックスの作成

次はインデックスを作成します。

『kuromoji_user_dict』というユーザ辞書指定をしたtokenizerと、それを使う『my_analyzer』というanalyzerを登録したindexを作成します。


curl -XPUT 'http://localhost:9200/kuromoji_sample/' -d'
{
    "settings": {
        "index":{
            "analysis":{
                "tokenizer" : {
                    "kuromoji_user_dict" : {
                       "type" : "kuromoji_tokenizer",
                       "mode" : "extended",
                       "discard_punctuation" : "false",
                       "user_dictionary" : "userdict_ja.txt"
                    }
                },
                "analyzer" : {
                    "my_analyzer" : {
                        "type" : "custom",
                        "tokenizer" : "kuromoji_user_dict"
                    }
                }

            }
        }
    }
}
'
{"acknowledged":true}

上記のindexが登録されたことを確認します。


http://localhost:9200/_aliases?pretty

{
  "kuromoji_sample" : {
    "aliases" : { }
  }
}

きちんと登録されていますね。

解析

最後に、解析ができるかをチェックします。


curl -XGET 'http://localhost:9200/kuromoji_sample/_analyze?analyzer=my_analyzer&pretty' -d '富士山'

{
  "tokens" : [ {
    "token" : "富士",
    "start_offset" : 0,
    "end_offset" : 2,
    "type" : "word",
    "position" : 1
  }, {
    "token" : "山",
    "start_offset" : 2,
    "end_offset" : 3,
    "type" : "word",
    "position" : 2
  } ]
}

成功です。

以上。

参考サイト
elasticsearch オススメ書籍

elasticsearchを使うなら側においておきたい一冊です。
うまくまとまっていて、辞書代わりにも利用できます。今のところ日本語の本を使うならこの本一択ですね。

この記事がお役にたちましたらシェアをお願いします

このエントリーをはてなブックマークに追加

2015年5月30日土曜日

chef(berkshelf)でelasticsearchをインストール

アプリにelasticsearchを導入したので忘備録的なメモ。
以前、この記事で利用方法をまとめましたが、こちらもナレッジを追加修正して随時更新していきます。
なお、今回elasticsearchの導入にはchefを使いました。

環境

  • rails(ruby2.2.2, rails4.2.1)
  • vagrant centOS6.5
  • chef11
  • elasticsearch1.5.2

berkshelf

Berksfileファイルに以下のcookbookを記載します。


cookbook 'elasticsearch'
cookbook 'java'

javaはversion8を使いたいので、cookbookに記載しました。version7で問題ない場合は、このcookbookは不要です。

berks vendor cookbooks


// 以前のcookbookは破棄する
rm -rf cookbooks
berks vendor cookbooks

roleの設定

role/elasticsearch.jsonを作成します。


{
  "name":"elasticsearch",
  "chef_type": "role",
  "json_class":"Chef::Role",
  "description":"tool server role",
  "run_list": [
    "recipe[java]",
    "recipe[elasticsearch]",
    "recipe[elasticsearch::plugins]"
  ],
  "default_attributes": {
    "java": {
      "install_flavor": "oracle",
      "jdk_version": 8,
      "java_home": "/usr/local/java",
      "oracle" : {
        "accept_oracle_download_terms": true
      }
    },
    "elasticsearch": {
        "version": "1.5.2"
    }
  }
}

elasticsearchは1.5.3を指定します。elasticsearch::pluginsでプラグインも指定しています。

pluginの設定

elasticsearchにはkuromojiを始めとして、様々なpluginが存在します。
これらのpluginを利用するために、installに必要な設定を記述します。


mkdir -p data_bugs/elasticsearch/

touch data_bugs/elasticsearch/plugins.json

plugins.jsonの記述

必要となるpluginを記載します。


{
    "id": "plugins",
    "_default": {
        "plugins": {
            "elasticsearch/elasticsearch-analysis-kuromoji": { "version": "2.5.0" },
            "royrusso/elasticsearch-HQ": {},
            "elasticsearch/marvel/latest": {},
            "polyfractal/elasticsearch-inquisitor": {}
        }
    }
}

chef-soloを実行

あとはいつも通りにchefを実行するだけです。


knife solo cook localhost

無事に実行が完了したら、localhost:9200に接続すると以下のjsonが表示されます。


{
  "status" : 200,
  "name" : "192.168.33.12",
  "cluster_name" : "elasticsearch",
  "version" : {
    "number" : "1.5.2",
    "build_hash" : "62ff9868b4c8a0c45860bebb259e21980778ab1c",
    "build_timestamp" : "2015-04-27T09:21:06Z",
    "build_snapshot" : false,
    "lucene_version" : "4.10.4"
  },
  "tagline" : "You Know, for Search"
}

続いてpluginのinstallを確認します。

urlにhttp://localhost:9200/_nodes/_all?plugin=true&prettyを指定します。


      // something(長いので省略) 

      "plugins" : [ {
        "name" : "analysis-kuromoji",
        "version" : "2.5.0",
        "description" : "Kuromoji analysis support",
        "jvm" : true,
        "site" : false
      }, {
        "name" : "marvel",
        "version" : "1.3.1",
        "description" : "Elasticsearch Management & Monitoring",
        "url" : "/_plugin/marvel/",
        "jvm" : true,
        "site" : true
      }, {
        "name" : "inquisitor",
        "version" : "NA",
        "description" : "No description found.",
        "url" : "/_plugin/inquisitor/",
        "jvm" : false,
        "site" : true
      }, {
        "name" : "HQ",
        "version" : "NA",
        "description" : "No description found.",
        "url" : "/_plugin/HQ/",
        "jvm" : false,
        "site" : true
      } ]

指定した4つのpluginがinstallされているのが確認できました。

以上

参考サイト

この記事がお役にたちましたらシェアをお願いします

このエントリーをはてなブックマークに追加

2015年2月8日日曜日

ElasticSearch 実戦に向けた学習 その1 バックアップと復元

ElasticSearch導入のための学習とメモ

環境

  • vagrant1.7.2
  • centos6.5

さて、その1,その2,その3で検索の基礎は理解できたので、実戦投入に向けた学習に切り替えます。あとは走りながらPDCAを回していきます。

運用で最低限利用しないと行けないのは、これまでの知識に加えて、

  • バックアップ
  • バックアップデータの復元
  • ログ
  • ユーザー辞書(必須ではないかな)

です。というわけでまずはバックアップから。(ElasticSearchではバックアップのことをスナップショットと読んでいるので、以降「スナップショット」で統一)

Snapshot And Restore

まずはテストデータの登録


curl -XPUT 'http://192.168.33.19:9200/game/nintendo/1' -d '
{
    "gama_name" :  "mario brothers",
    "main_character_name" :   "marip",
    "price" : 5000
}
'

curl -XPUT 'http://192.168.33.19:9200/game/nintendo/2' -d '
{
    "gama_name" :  "zelda",
    "main_character_name" :   "Smith",
    "price" : 6000
}
'

curl -XPUT 'http://192.168.33.19:9200/game/nintendo/3' -d '
{
    "gama_name" :  "donkey kong",
    "main_character_name" : "donkey",
    "price" : 7000
}
'

// 検索
curl -XGET 'http://192.168.33.19:9200/game/nintendo/_count?pretty' -d '
{
    "query": {
        "match_all": {}
    }
}
'

// 結果
{
  "count" : 3,
  "_shards" : {
    "total" : 5,
    "successful" : 5,
    "failed" : 0
  }
}


データ登録が完了したら、スナップショットを作成します。

repositories

スナップショットの作成の前にrepositoryを作成します。


// snapshot用のフォルダを作成
mkdir -p /var/elastic_search/my_backup

// フォルダの権限をelastic_searchにする
sudo chown elasticsearch:elasticsearch /var/elastic_search/my_backup/

// repository登録する
curl -XPUT 'http://192.168.33.19:9200/_snapshot/my_backup' -d '{
    "type": "fs",
    "settings": {
        "location": "/var/elastic_search/my_backup",
        "compress": true
    }
}
'

// 結果
{"acknowledged":true}

上手くいったみたいですね。一応コマンドから確認してみましょう。


curl -XGET 'http://192.168.33.19:9200/_snapshot/my_backup?pretty'

// 結果
{
  "my_backup" : {
    "type" : "fs",
    "settings" : {
      "compress" : "true",
      "location" : "/var/elastic_search/my_backup"
    }
  }
}

リポジトリが作成できたので、スナップショットを作成します。が、その前に理解しておかないといけないスナップショットの仕様を以下にまとめ。

  • スナップショットはclusterの中の、一意な名称によって特定される。
  • http://192.168.33.19:9200/_snapshot/my_backup/snapshot_1なら「my_backup」がリポジトリで「snapshot_1」がスナップショット。
  • index スナップショットを作成する過程で、Elasticsearchはリポジトリの中に保存されたindexファイルの一覧を分析する。そして、最後のスナップショットから変更、もしくは作成されたファイルだけを保存する。
  • スナップショットがリポジトリから削除された時、Elasticsearchはリポジトリがスナップショットを保存している場所の参照だけ削除する。つまり、スナップショット自体はその場に残っている。

スナップショットを作成


// 作成
curl -XPUT "http://192.168.33.19:9200/_snapshot/my_backup/snapshot_1?wait_for_completion=true"

// 結果
{"snapshot":{"snapshot":"snapshot_1","indices":["game","test","megacorp"],"state":"SUCCESS","start_time":"2015-02-06T06:59:29.624Z","start_time_in_millis":1423205969624,"end_time":"2015-02-06T06:59:30.186Z","end_time_in_millis":1423205970186,"duration_in_millis":562,"failures":[],"shards":{"total":15,"failed":0,"successful":15}}}

全てのindexが保存されていますね。リクエストのjsonでスナップショットを作成したいindexだけを指定することもできます。

さて、スナップショットを作成したので、データを変更してみましょう。index[game]にデータを2件追加します。


// データ登録
curl -XPUT 'http://192.168.33.19:9200/game/nintendo/4' -d '
{
    "gama_name" :  "metoroido",
    "main_character_name" :   "Samusu",
    "price" : 7000
}
'

// データ登録
curl -XPUT 'http://192.168.33.19:9200/game/nintendo/5' -d '
{
    "gama_name" :  "pokemon",
    "main_character_name" :   "Pikachu",
    "price" : 8000
}
'

// 検索
curl -XGET 'http://192.168.33.19:9200/game/nintendo/_count?pretty' -d '
{
    "query": {
        "match_all": {}
    }
}
'

// 結果
{
  "count" : 5,
  "_shards" : {
    "total" : 5,
    "successful" : 5,
    "failed" : 0
  }
}

3件から5件にデータが増えました。
次はバックアップデータの復元をしましょう。(ElasticSearchではバックアップデータの復元のことをリストアと読んでいるので、以降「リストア」で統一)


// リストア
curl -XPOST "http://192.168.33.19:9200/_snapshot/my_backup/snapshot_1/_restore" -d '{
    "indices": "game",
    "rename_pattern": "game",
    "rename_replacement": "game2"
}'

// 検索
curl -XGET 'http://192.168.33.19:9200/game2/nintendo/_count?pretty' -d '
{
    "query": {
        "match_all": {}
    }
}
'

// 結果
{
  "count" : 3,
  "_shards" : {
    "total" : 5,
    "successful" : 5,
    "failed" : 0
  }
}

curl -XGET "http://192.168.33.19:9200/_aliases?pretty"

rename_patternとrename_replacementを指定しないと"error":"SnapshotRestoreException[[my_backup:snapshot_1] cannot restore index [game] because it's openが発生した。なぜ同じ名前だとリストアができないのだろうか。

indexの一覧を確認する


// indexの一覧を確認
curl -XGET "http://192.168.33.19:9200/_aliases?pretty"

// 結果
{
  "game" : { },
  "test" : { },
  "megacorp" : { },
  "game2" : { }
}


indexが増えています。indexが存在しているとリストアができないのかもしれない。indexを削除、リストアの順かな。


// game index削除
curl -XDELETE 'http://192.168.33.19:9200/game/'

// game2 index削除
curl -XDELETE 'http://192.168.33.19:9200/game2/'

// indexの一覧を確認
curl -XGET "http://192.168.33.19:9200/_aliases?pretty"

// 結果
{
  "test" : { },
  "megacorp" : { }
}

// リストア
curl -XPOST "http://192.168.33.19:9200/_snapshot/my_backup/snapshot_1/_restore" -d '{
    "indices": "game"
}
'

// 結果
{"accepted":true}

// indexの一覧を確認
curl -XGET "http://192.168.33.19:9200/_aliases?pretty"

// 結果
{
  "test" : { },
  "megacorp" : { }
}

// game indexの確認
curl -XGET 'http://192.168.33.19:9200/game/nintendo/_count?pretty' -d '
{
    "query": {
        "match_all": {}
    }
}
'

// 結果
{
  "count" : 3,
  "_shards" : {
    "total" : 5,
    "successful" : 5,
    "failed" : 0
  }
}

ビンゴ!!。リストアでデータを復活させる場合は、indexを削除しないといけないようである。

さて、次はログの学習です。

では、また。

参照

この記事がお役にたちましたらシェアをお願いします

このエントリーをはてなブックマークに追加

ElasticSearch 決定版ガイドで学習 その3

ElasticSearch導入のための学習とまとめ。

環境

  • vagrant1.7.2
  • centos6.5

Search with Query DSL

JSON request bodyを使って検索ができる。


curl -XGET http://192.168.33.19:9200/megacorp/employee/_search -d '
{
    "query" : {
        "match" : {
            "last_name" : "Smith"
        }
    }
}'

// 結果

{"took":7,"timed_out":false,"_shards":{"total":5,"successful":5,"failed":0},"hits":{"total":2,"max_score":0.30685282,"hits":[{"_index":"megacorp","_type":"employee","_id":"1","_score":0.30685282,"_source":
{
    "first_name" : "John",
    "last_name" :  "Smith",
    "age" :        25,
    "about" :      "I love to go rock climbing",
    "interests": [ "sports", "music" ]
}
},{"_index":"megacorp","_type":"employee","_id":"2","_score":0.30685282,"_source":
{
    "first_name" :  "Jane",
    "last_name" :   "Smith",
    "age" :         32,
    "about" :       "I like to collect rock albums",
    "interests":  [ "music" ]
}
}]}}

More-Complicated Searches

もうちょい複雑な検索をしてみる。filterを利用する。


curl -XGET http://192.168.33.19:9200/megacorp/employee/_search -d '
{
    "query" : {
        "filtered" : {
            "filter" : {
                "range" : {
                    "age" : { "gt" : 30 } 
                }
            },
            "query" : {
                "match" : {
                    "last_name" : "smith" 
                }
            }
        }
    }
}'

// 結果
{"took":11,"timed_out":false,"_shards":{"total":5,"successful":5,"failed":0},"hits":{"total":1,"max_score":0.30685282,"hits":[{"_index":"megacorp","_type":"employee","_id":"2","_score":0.30685282,"_source":
{
    "first_name" :  "Jane",
    "last_name" :   "Smith",
    "age" :         32,
    "about" :       "I like to collect rock albums",
    "interests":  [ "music" ]
}
}]}}

gtはgreater than。

Full-Text Search & Phrase Search

さらにもうちょい複雑な検索をしてみる。rock climbingが趣味のユーザーを取得する。


curl -XGET http://192.168.33.19:9200/megacorp/employee/_search -d '
{
    "query" : {
        "match_phrase" : {
            "about" : "rock climbing"
        }
    }
}'

// 結果

{"took":7,"timed_out":false,"_shards":{"total":5,"successful":5,"failed":0},"hits":{"total":1,"max_score":0.23013961,"hits":[{"_index":"megacorp","_type":"employee","_id":"1","_score":0.23013961,"_source":
{
    "first_name" : "John",
    "last_name" :  "Smith",
    "age" :        25,
    "about" :      "I love to go rock climbing",
    "interests": [ "sports", "music" ]
}
}]}}

"rock" と "climbing" の両方を含んでいるデータを取得する場合は、match_phraseで検索する。matchだと"rock" と "climbing"のいづれか一つのフレーズがマッチしただけで結果を取得することになる。

Highlighting Our Searches

ハイライトさせたいときはhighlight parameterを加える。


curl -XGET http://192.168.33.19:9200/megacorp/employee/_search -d '
{
    "query" : {
        "match_phrase" : {
            "about" : "rock climbing"
        }
    },
    "highlight": {
        "fields" : {
            "about" : {}
        }
    }
}'

// 結果

{"took":51,"timed_out":false,"_shards":{"total":5,"successful":5,"failed":0},"hits":{"total":1,"max_score":0.23013961,"hits":[{"_index":"megacorp","_type":"employee","_id":"1","_score":0.23013961,"_source":
{
    "first_name" : "John",
    "last_name" :  "Smith",
    "age" :        25,
    "about" :      "I love to go rock climbing",
    "interests": [ "sports", "music" ]
}
,"highlight":{"about":["I love to go rock climbing"]}}]}}

Analytics

集合を操れる。ここは割愛。上記までのやり方が理解できてれば、全然難しくない。
ここより先は、必要な時、もっと理解を深めたいときに読むと良いとのこと。

というわけで導入の決定版ガイドで学習は終了になります。次は既存のmysqlと連携して利用してみようと思います。
また具体的に学習する項目があれば、こんな感じでやっていこうと思います。

では、また。

この記事がお役にたちましたらシェアをお願いします

このエントリーをはてなブックマークに追加

2015年2月6日金曜日

ElasticSearch 決定版ガイドで学習 その2

ElasticSearch導入のための学習とまとめ。

環境

  • vagrant1.6.5
  • centos6.5

Talking to Elasticsearch

Elasticsearchへリクエストを送る場合、以下の構文を使用する


curl -X<VERB> '<PROTOCOL>://<HOST>/<PATH>?<QUERY_STRING>' -d '<BODY>'

例:クラスターの中のドキュメントの数をカウント

コマンドで叩きます


curl -XGET 'http://192.168.33.19:9200/_count?pretty' -d '
{
    "query": {
        "match_all": {}
    }
}
'

// 結果
{
  "count" : 0,
  "_shards" : {
    "total" : 0,
    "successful" : 0,
    "failed" : 0
  }
}

まだ何もやってないので、全部0なのかな。多分。header情報も見たいときはcurlに-iオプションを追加する。


curl -i -XGET 'http://192.168.33.19:9200/'
HTTP/1.1 200 OK
Content-Type: application/json; charset=UTF-8
Content-Length: 347

{
  "status" : 200,
  "name" : "Hate-Monger",
  "cluster_name" : "elasticsearch-changed",
  "version" : {
    "number" : "1.4.2",
    "build_hash" : "927caff6f05403e936c20bf4529f144f0c89fd8c",
    "build_timestamp" : "2014-12-16T14:11:12Z",
    "build_snapshot" : false,
    "lucene_version" : "4.10.2"
  },
  "tagline" : "You Know, for Search"
}

ちゃんとheaderが表示できましたね。

Document Oriented

Elasticsearchはドキュメントベースでデータを管理し、jsonを利用している。indexもドキュメント。

Finding Your Feet

チュートリアルをやってElasticsearchを理解しよう。ここでは従業員のディレクトリを作ってチャレンジするよ。要件は以下

  • 複数のタグ、値、数値、テキストを含むデータを利用できる
  • あらゆる従業員の詳細を検索する
  • 30歳以上の従業員を見つけるような、構造化された検索を許可
  • 単純なフルテキスト検索と、より複雑なフレーズ検索を許可
  • 一致するドキュメントのテキストの中から、強調された検索の断片を返す
  • 分析的なダッシュボードを作成できる

Indexing Employee Documents

Elasticsearchにデータを保存することを「indexing」と呼ぶ。
「indexing」の前に保存場所を決める。
Elasticsearchでは、documentはtypeに属する。これらのtypeはindexの中にあるよ。

Relational DB ⇒ Databases ⇒ Tables ⇒ Rows ⇒ Columns
Elasticsearch ⇒ Indices ⇒ Types ⇒ Documents ⇒ Fields

データの登録


curl -XPUT 'http://192.168.33.19:9200/megacorp/employee/1' -d '
{
    "first_name" : "John",
    "last_name" :  "Smith",
    "age" :        25,
    "about" :      "I love to go rock climbing",
    "interests": [ "sports", "music" ]
}
'

{"_index":"megacorp","_type":"employee","_id":"1","_version":1,"created":true}

/megacorp/employee/1に3つの情報が含まれているのに注意。

megacorp : The index name
employee : The type name
1 :The ID of this particular:employee

うまく登録できたみたいなので、ブラウザから叩く。


// ブラウザで叩く
http://192.168.33.19:9200/megacorp/employee/1

// 結果表示

{"_index":"megacorp","_type":"employee","_id":"1","_version":1,"found":true,"_source":
{
    "first_name" : "John",
    "last_name" :  "Smith",
    "age" :        25,
    "about" :      "I love to go rock climbing",
    "interests": [ "sports", "music" ]
}
}

成功です。どんどん登録します。


// 登録

curl -XPUT 'http://192.168.33.19:9200/megacorp/employee/2' -d '
{
    "first_name" :  "Jane",
    "last_name" :   "Smith",
    "age" :         32,
    "about" :       "I like to collect rock albums",
    "interests":  [ "music" ]
}
'

// 登録

curl -XPUT 'http://192.168.33.19:9200/megacorp/employee/3' -d '
{
    "first_name" :  "Douglas",
    "last_name" :   "Fir",
    "age" :         35,
    "about":        "I like to build cabinets",
    "interests":  [ "forestry" ]
}
'

// 確認

curl -XGET 'http://192.168.33.19:9200/_count?pretty' -d '
{
    "query": {
        "match_all": {}
    }
}
'

{
  "count" : 3,
  "_shards" : {
    "total" : 5,
    "successful" : 5,
    "failed" : 0
  }
}

Search Lite

簡単な検索の学習。まずは「単純検索」


// ブラウザ
http://192.168.33.19:9200/megacorp/employee/_search

{"took":22,"timed_out":false,"_shards":{"total":5,"successful":5,"failed":0},"hits":{"total":3,"max_score":1.0,"hits":[{"_index":"megacorp","_type":"employee","_id":"1","_score":1.0,"_source":
{
    "first_name" : "John",
    "last_name" :  "Smith",
    "age" :        25,
    "about" :      "I love to go rock climbing",
    "interests": [ "sports", "music" ]
}
},{"_index":"megacorp","_type":"employee","_id":"2","_score":1.0,"_source":
{
    "first_name" :  "Jane",
    "last_name" :   "Smith",
    "age" :         32,
    "about" :       "I like to collect rock albums",
    "interests":  [ "music" ]
}
},{"_index":"megacorp","_type":"employee","_id":"3","_score":1.0,"_source":
{
    "first_name" :  "Douglas",
    "last_name" :   "Fir",
    "age" :         35,
    "about":        "I like to build cabinets",
    "interests":  [ "forestry" ]
}
}]}}

「条件を付加して検索」


// ブラウザ
http://192.168.33.19:9200/megacorp/employee/_search?q=last_name:Smith

{"took":22,"timed_out":false,"_shards":{"total":5,"successful":5,"failed":0},"hits":{"total":2,"max_score":0.30685282,"hits":[{"_index":"megacorp","_type":"employee","_id":"1","_score":0.30685282,"_source":
{
    "first_name" : "John",
    "last_name" :  "Smith",
    "age" :        25,
    "about" :      "I love to go rock climbing",
    "interests": [ "sports", "music" ]
}
},{"_index":"megacorp","_type":"employee","_id":"2","_score":0.30685282,"_source":
{
    "first_name" :  "Jane",
    "last_name" :   "Smith",
    "age" :         32,
    "about" :       "I like to collect rock albums",
    "interests":  [ "music" ]
}
}]}}

長くなるので分割。
次はSearch with Query DSLからです。
どこまできちんとメモするか微妙です。

この記事がお役にたちましたらシェアをお願いします

このエントリーをはてなブックマークに追加

ElasticSearch 決定版ガイドで学習 その1

ElasticSearch導入のための学習とまとめ。後でもっと綺麗にまとめます。多分・・・。

環境

  • vagrant1.6.5
  • centos6.5

javaをinstall

Elasticsearchを動かすにはjavaが必要なのでインストール


// 動作に必要なjavaの導入
yum install java-1.7.0-openjdk

Elasticsearch install

rpm版をダウンロードして利用します


// rpm DLしてinstall
sudo rpm -ivh https://download.elasticsearch.org/elasticsearch/elasticsearch/elasticsearch-1.4.2.noarch.rpm

### NOT starting on installation, please execute the following statements to configure elasticsearch to start automatically using chkconfig
 sudo /sbin/chkconfig --add elasticsearch
### You can start elasticsearch by executing
 sudo service elasticsearch start

// chkconfigは有効にしないで実行
sudo service elasticsearch start

ブラウザを開いてhttp://192.168.33.19:9200/にアクセス。(192.168.33.19はvagrantで適当に指定)


{
  "status" : 200,
  "name" : "Brigade",
  "cluster_name" : "elasticsearch",
  "version" : {
    "number" : "1.4.2",
    "build_hash" : "927caff6f05403e936c20bf4529f144f0c89fd8c",
    "build_timestamp" : "2014-12-16T14:11:12Z",
    "build_snapshot" : false,
    "lucene_version" : "4.10.2"
  },
  "tagline" : "You Know, for Search"
}

きちんと動作しています。

さて、まずは基本からきっちり学んでいきましょう。急がばまわれはいつの時代、どこの世界も共通項。

まずは公式サイトのdefinitive guideに目を通します。せっかくなので日本語に翻訳した超短縮要訳も載せておきます。

決定版ガイド超短縮要訳

who should read this book

Elasticsearchは素晴らしい技術だよ。規約に沿っている限りは、楽々スケールできる。
製品版の前に安定したクラスターの作り方を理解しなさい。
メルトダウンを避けるためにもガイドは読もうな。

Why We Wrote This Book

Elasticsearchは説明が必要だ。このガイドは初心者に理解できるように書いたよ。
既存のリファレンスドキュメントは機能の使い方を説明している。このガイドでは、なぜ、そしていつ、Elasticsearchの様々な機能を使うべきかを説明しよう。

Elasticsearch version

1.4.0について説明する。でも、すぐ進化するから気をつけてね。

How to Read This Book

複雑なプロセスもきちんと理解しよう。
Life Inside a Cluster, Distributed Document Store, Distributed Search Execution, and Inside a Shardを読むと理解が深くなるよ。だから、ちゃんと読んどきー。
最初は順番に読んでいきなさい。Proximity Matching and Partial Matchingは必要に応じて読みなさい。

Navigating This Book

7つのパートがある

「you know, for search」…から「Inside a Shard」は基本。いいからやれ。

「Structured search…」から「Controlling Relevance」は文字の有意(確率的に偶然とは考えにくく、意味があると考えられる)性や部分マッチ。

「Getting Started with Languages」から「Typoes and Mispelings」は語幹処理、類語、あいまい検索。

online resources, conventions used in this book,using code examples, acknowledgments

不要

you know, for search

Luceneは素晴らしい検索エンジンだが複雑だ。Elasticsearchはもっと素晴らしい検索エンジンなうえに簡単だ。

Installing Elasticsearch

marvel入れるとブラウザで見れて便利だよ。無料じゃないので注意。

Installing Elasticsearch

cluster.nameはデフォルトでなく、適当な名称に変更しなさい。同じネットワーク内で動かすなら一意な名前にしないと駄目だよーん。
cluster.nameはconfigディレクトリのelasticsearch.ymlを変更して再起動すれば変更できます。


// conf
cd /etc/elasticsearch

ls -l
-rw-r--r-- 1 root root 13476 Dec 16 14:12 elasticsearch.yml
-rw-r--r-- 1 root root  1512 Dec 16 14:12 logging.yml

vi elasticsearch.yml


################################### Cluster ###################################

# Cluster name identifies your cluster for auto-discovery. If you're running
# multiple clusters on the same network, make sure you're using unique names.
#
cluster.name: elasticsearch-changed

再起動して、ブラウザを開いてhttp://192.168.33.19:9200/に再びアクセス。


// 再起動
sudo service elasticsearch restart

{
  "status" : 200,
  "name" : "Hate-Monger",
  "cluster_name" : "elasticsearch-changed",
  "version" : {
    "number" : "1.4.2",
    "build_hash" : "927caff6f05403e936c20bf4529f144f0c89fd8c",
    "build_timestamp" : "2014-12-16T14:11:12Z",
    "build_snapshot" : false,
    "lucene_version" : "4.10.2"
  },
  "tagline" : "You Know, for Search"
}

cluster_nameが変更されているのが確認できました。

シャットダウンは、Ctrl-Cか、shutdown APIを呼びだしなさい


curl -XPOST 'http://192.168.33.19:9200/_shutdown'

コマンド叩くとelasticsearchが止まります。

長くなるので続きます。
次はTalking to Elasticsearchからです。

参照

この記事がお役にたちましたらシェアをお願いします

このエントリーをはてなブックマークに追加
Related Posts Plugin for WordPress, Blogger...