RSS2.0

ElasticSearch でインデックス時と全文検索時で異なる analyzer を設定する

前回は ElasticSearch が全文検索クエリを処理する際の分かち書きのしくみについてふれました。ElasticSearch ではさまざまな種類の tokenizer を中心に analyzer を設計することができ、この analyzer が実際に文字列の単語分割を行ってくれます。

ElasticSearch ではインデックスに格納するドキュメントの内容(フィールドの値)と、全文検索クエリの検索キーワードに対して分かち書きが行われますが、この 2 つに対して異なる analyzer を適用することができます。今回は、インデックスにドキュメントを格納する際の転値インデックス作成時と、検索キーワードを渡した全文検索クエリでの検索時とで、異なる analyzer を利用してみたいと思います。

インデックス時と全文検索時の analyzer の単語分割結果を確認する

ElasticSearch では、インデックスにドキュメントを格納する際の転値インデックス作成時に適応される analyzer と、全文検索クエリで渡される検索キーワードに適用される analyzer を設定できます。となるとインデックス時と全文検索時に動作している analyzer の処理結果をそれぞれ確認したいということになると思います。まずはじめにこれらの分かち書きの結果を確認する方法についてみておきます。
続きを読む ElasticSearch  コメント (1) 2018/10/12 17:43:15

ElasticSearch の全文検索での analyzer について

前回の ElasitcSearch での文書検索についての記事の中で、ElasticSearch の中核となる機能である全文検索クエリについて触れました。

ElasticSearch の全文検索クエリでは、文書を単語に分割する分かち書きという工程を経て、その単語が含まれる文書が検索されます。しかし、はたして何を単語とみなすかというのは難しい問題です。普段人間が使っている言葉の種類は国や言語、時代によって膨大な量になりますし、常に新しい言葉、失われていく言葉が存在しています。また同じ言葉でも文脈や使われる分野によって意味が変わったり、1 つの言葉なのに文字で表現しようとすると何通りも書き方があったりします。現時点ではあらゆる単語を分かち書きできるような技術は残念ながら存在していないので、全文検索を適用したい分野にあわせてどのように分かち書きしていくかを自分で設計していく必要があります。

ElasticSearch では単語分割は analyzer によって処理されます。この analyzer には単語分割に関わる言語処理機能を必要に応じて組みあわせて使えるようになっています。今回はこの analyzer がどのように分かち書きを行っていくのか、ElasticSearch の analyzer による言語処理機能の具体例を見ていこうと思います。

analyzer による単語分割の流れ

ElasticSearch における analyzer は、分かち書きする文字列中の各文字を追加/変更/削除する character filtercharacter filter から受け取った文字列を実際に単語に分割する tokenizertokenizer が分割した単語の列から単語単位で追加/変更/削除する token filter の 3 つによって構成されています。analyzer には必ず 1 つの tokenizer が設定されていなければなりませんが、character filter と token filter はオプションとなっていて、任意の数を設定することができます。

一応定義どおりに analyzer の構成要素を説明するとこうなるのですが、感覚としては、中心となる tokenizer が単語分割しやすいように tokenizer の前処理 / 後処理として必要なフィルターを設定していく、くらいで良いと思います。ElasticSearch にあらかじめ組み込まれているビルトインの token filter には、どちらかというと character filter としてあるべきなのではと思うものもあったりします。また高機能な tokenizer には、他のビルトインのフィルターと同等の機能を内包していたりするものもあります。
続きを読む ElasticSearch  コメント (0) 2018/10/11 19:07:40

ElasticSearch で文書を検索をしてみる

ElasticSearch で提供されている代表的な文書の検索機能には、全文検索クエリと Term ベースクエリがあります。全文検索クエリは、検索時のキーワードが含まれているるドキュメントを探し出すための検索クエリです。一方 Term ベースクエリは、検索時のキーワードが完全に一致するドキュメントを探し出すための検索クエリになります。

よくある検索エンジンのようにキーワードが含まれている WEB ページを探すというような用途では全文検索クエリが適していますが、ユニークなキー値のようなものをキーワードにして、そのキー値が割り当てられている文書を探すような用途では Term ベースクエリが適しています。全文検索クエリではあらかじめ文書が単語に分割されて、その単語に対して検索が行われますが、Term ベースクエリでは文書が単語に分割されず、キーワードと完全一致するかで検索されます。ユニークなキー値で検索を行う場合、そのキーワードの一部分ではなくすべてが完全に一致するドキュメントを検索しなければならないので、Term ベースクエリの方が適していることになります。

今日はこの全文検索クエリと Term ベースクエリについて、実際にインデックスを作りながら試していきたいと思います。

検証データを用意する

前提として、今回は以下のインデックスを使うものとします。
$ curl -XPUT http://localhost:9200/samurai -H "Content-type: application/json" -d '{
  "settings": {
    "number_of_replicas": 0,
    "number_of_shards": 1,
    "analysis": {},
    "refresh_interval": "1s"
  },
  "mappings": {
    "_doc": {
      "properties": {
        "name": {
          "type": "keyword"
        },
        "description": {
          "type": "text"
        }
      }
    }
  }
}'
このマッピングでは、name フィールドは keyword 型、description フィールドは text 型としています。

また、このインデックスには以下のドキュメントを入れておきます。
$ curl -XPOST http://localhost:9200/_bulk -H "Content-type: application/json" -d '
{ "index": { "_index": "samurai", "_type": "_doc" } }
{ "name": "真田昌幸", "description": "甲斐国の武田信玄の家臣となり信濃先方衆となった地方領主真田氏の出自で、真田信之、真田幸村の父。" }
{ "index": { "_index": "samurai", "_type": "_doc" } }
{ "name": "真田信之", "description": "真田昌幸の長男。徳川家康の養女を妻としていたため関ヶ原の戦いでは東軍につき、江戸時代には松代藩藩主をつとめた。" }
{ "index": { "_index": "samurai", "_type": "_doc" } }
{ "name": "真田幸村", "description": "真田昌幸の次男。豊臣家臣の大谷吉継の娘を妻としていたため関ヶ原の戦いでは西軍につき、父真田昌幸とともに戦死した。" }
{ "index": { "_index": "samurai", "_type": "_doc" } }
{ "name": "石田三成", "description": "豊臣政権の五奉行の一人。秀吉の死後、徳川家康を倒すため決起するが、関ヶ原の戦いで敗れ、その後処刑された。" }
{ "index": { "_index": "samurai", "_type": "_doc" } }
{ "name": "徳川家康", "description": "豊臣秀吉の天下統一後に台頭した武将で、関ヶ原の戦いに勝利し、江戸幕府を開いた。" }
'

続きを読む ElasticSearch  コメント (1) 2018/10/10 20:00:43

ElasticSearch 6.4.2 をさわってみた

データを全文検索するためのエンジンである ElasticSearch を触っていきたいと思います。全文検索というと WEB ページや文書のキーワード検索として広く利用されていますが、最近では RDB への参照性能を改善するため、代替手段として使われる場面も多いようです。RDB から適切なタイミングでデータを同期してやる必要があるものの、複数のテーブルやデータベースから必要なデータのみを集約して参照させるという用途では、RDB よりもはるかに高速にアクセスでき、RDB とは切り離した擬似的な参照系として構築できる点が評価されているようです。

ElasticSearch も他の分散システムと同じくノードを複数台用意したクラスター構成をとることができますが、今回は手始めということで、シングルノード構成での環境構築からやってみたいと思います。

ElasticSearch をインストールする

公式サイトのダウンロードページから ElasticSearch の最新版をダウンロードします。現時点での最新版は 6.4.2 でした。Linux 向けには rpm パッケージが公開されていたので、これを使うことにします。
ダウンロードした rpm パッケージをインストールします。
# rpm -ivh elasticsearch-6.4.2.rpm

ElasticSearch をインストールすると、/etc/elasticsearch/elasticsearch.yml として設定ファイルが作られます。シングルノード構成の場合には特に elasticsearch.yml を編集しなくても動くのですが、複数ノード構成でクラスターを組む場合には書き変えてやる必要があります。

インストールした ElasticSearch は、systemctl start コマンドから起動できます。
 
# systemctl start elasticsearch.service
また、自動起動を有効化する場合は systemctl enable しておきましょう。
# systemctl enable elasticsearch.service

続きを読む ElasticSearch  コメント (0) 2018/10/09 20:05:50
プロフィール HN: ももかん
ゲーム作ったり雑談書いたり・・・していた時期が私にもありました。
カレンダー
<<2024, 11>>
272829303112
3456789
10111213141516
17181920212223
24252627282930