どこにでもいるSEの備忘録

たぶん動くと思うからリリースしようぜ

ElasticStackの使い方(その1 : ElasticSearch)

f:id:nogawanogawa:20190216065256p:plain

この前こんな事やってました。

nogawanogawa.hatenablog.com

何を血迷ったか、使ったことのないElasticSearchを使ってしまって、使い方がよくわからなくなって一回挫折しました。

そうは言ってもElasticStackの使い方は覚えておいて損はないので、ElasticStackの勉強をしてみたのでその覚え書きです。

参考にさせていただいたのはこちら。

Introduction of Elastic Stack 6 これからはじめるデータ収集&分析 (技術書典シリーズ(NextPublishing))

Introduction of Elastic Stack 6 これからはじめるデータ収集&分析 (技術書典シリーズ(NextPublishing))

初めて技術書典の本を読みました。 比較的新しめの技術とか尖った分野について日本語で勉強したいときなんかに意外と重宝しそうな感じです。

その他、Webinarも見て勉強しました。

www.elastic.co

こちらも効率的に学習するにはいいと思いました。

ElasticStack

Elastic社が提供しているデータ分析基盤群ですね。 検索やデータ収集、可視化など一通りをやってくれる製品が揃っています。

www.elastic.co

その中に下記のような製品が揃っている形になります。

  • ElasticSearch
  • Kibana
  • LogStash
  • Beats

基本無料です。基本無料です。大事なことなので二回言いました。

ElasticSearch

ElasticSearchはJavaで作られている分散処理型検索エンジンです。 その用途としては、リアルタイムデータ分析、ログ解析、全文検索などが上げられます。

RESTFulなAPIを提供しており、データの編集、検索は基本的にjson形式でやりとりが行われます。

用語

RDBと対比して用語の説明を下記に示します。

ElasticSearch RDBでいうと 意味
Index スキーマ/データベース ElasticSearchが検索・解析の対象とするデータの保存先
Type テーブル Indexの中のグループ、テーブル
Field カラム ドキュメントに含まれる属性
Document レコード ElasticSearchに保存されたデータ

※ElasticSearch 6.x系以降では1indexあたり1Typeしか使用できず、7.x系からはTypeの存在はなくなる予定です。 同じindexには一つのテーブルしか用意できないので、複数分けたいときはindexを分ける必要があります。

Mapping (スキーマ)

ElasticSearch自体はスキーマレス、つまりテーブル構造を定める必要は無いのですが、実際のところ管理の都合上、予めスキーマを決めるのが一般的だと思います。

Mappingを定義することで、いわゆるスキーマを定義していくことになります。 こんな感じのjsonを書いて定義していきます。

{
  "mappings" : {
    "Type名" : {
      "properties" : {
        "要素1" : {
          "type" : "型"
        },
        "要素2" : {
          "type" : "型"
        }
      }
    }
  }
}

こんな感じにField名とデータ型を指定していきます。 そして、入力時にサーバーとindexを指定します。

curl -XPUT サーバーアドレス/<index名> -H "Content-Type:application/json" -d @mapping.json

こんな感じにmappingを定義します。 ちなみにContent-Typeはちゃんと書かないとエラーになります。

ドキュメントの追加/削除

この本だとGoでやっているんですがいかんせんGoは専門外なので、今回はPythonでやります。 基本的には、追加/削除したいデータをjsonで記述して、それをPUTで送信するだけです。

ドキュメントの追加

ドキュメントの追加はこんな感じです。

index関数を使って投入していきます。

$python3 index.py
{'_index': 'sample', '_type': 'sample', '_id': 'HDt7-mgBzCOa82T5Sg_N', '_version': 1, 'result': 'created', '_shards': {'total':
 2, 'successful': 1, 'failed': 0}, '_seq_no': 0, '_primary_term': 1}

ドキュメントの削除

ドキュメントの削除はこんな感じですね。

delete関数を使って削除していきます。引数のidは先程indexしたときの戻り値を指定しています。

$python3 delete.py
{'_index': 'sample', '_type': 'sample', '_id': 'HDt7-mgBzCOa82T5Sg_N', '_version': 2, 'result': 'deleted', '_shards': {'total':
 2, 'successful': 1, 'failed': 0}, '_seq_no': 1, '_primary_term': 1}

検索

ElasticSearchでの検索クエリには、いくつかの手法がサポートされており、その中から適切なものを選択することになります。

  • Match Query : Analyzerによる解析付き検索
  • Term Query : Analyzerによる解析なし検索
  • Bool Query : AND/ORなどを駆使して検索

Analyzer

検索というと簡単に聞こえるかもしれませんが、中では結構めんどくさいことをやっています。

f:id:nogawanogawa:20190217172630j:plain:w500

まず、特に日本語は、形態素解析をして適切な単語に区切り、それらを使用して評価式を適用することで、scoreを算出することで、ユーザーが要求するドキュメントを探し出します。

Analyzer内部での解析器には大きく3種類あり、これらを設定することで検索エンジンの挙動を調整していくことが可能です。

  • Tokenizer : 形態素解析N-gramなど、単語の分割を行う
  • Character Filters : 文字の調整(大文字、小文字、全角、半角)などを行う
  • Token Filters : Stop wordなどの除去を行う

Analyzerの設定

analizerの調整はこんな感じのjsonを書きます。

上半分でElasticSearch自体の設定、下半分でMappingに対してどの解析を適用させるかを記述しています。

後はさっきと同じように適用すれば、analyzerの調整が内部的に行われます。

検索

こんな感じですね。

他にもいろいろ出来るみたいですが、基本はこの辺だけ使えれば問題ないでしょう。 なんか便利そうなの見つけたら追記します。

その他

なにやらPDFとかMSOffice系もattachmentってのを使えば、そのまま突っ込んで、検索に引っかけられるみたいです。

tombo2.hatenablog.com

勉強になります。

感想

この本読む前はあんまり良くわかってなかったですが、ちょっとだけElasticSeatchの仕組みというかお作法がわかった気がします。 勉強になりました。