Elasticsearchでの全文検索


本記事は東京学芸大学 櫨山研究室 Advent Calendar 2020の十一日目の記事になります.

はじめに

本記事ではElasticsearchをDockerで構築し,RESTful APIを使ってElasticsearchにドキュメントを登録・検索する手順を扱います.

Elasticsearchの準備

ElasticsearchはElastic社が開発している全文検索エンジンです.
今回はDockerで起動します.

バージョンは7.10を使用します.

Dockerfile
FROM docker.elastic.co/elasticsearch/elasticsearch:7.10.0
RUN elasticsearch-plugin install analysis-kuromoji

日本語を対象とした全文検索を行うためkuromojiプラグインを導入しています.

ポートや環境変数の設定をしたいのでdocker-compose.ymlを用意します.

docker-compose.yml
version: '3.7'

services:
 elasticsearch:
    container_name: elasticsearch
    build: ./
    environment:
      - discovery.type=single-node
      - cluster.name=docker-cluster
      - bootstrap.memory_lock=true
      - "ES_JAVA_OPTS=-Xms512m -Xmx512m"
    ports:
      - 9200:9200
    tty: true

docker-compose upコマンドで立ち上げます.

bash
docker-compose up

正常に起動したらcurlコマンドでリクエストを送ってみましょう.
レスポンスがきちんと返ってくれば正常に動いています🙆‍♂️

bash
curl http://localhost:9200
{
  "name" : "a868b38a737e",
  "cluster_name" : "docker-cluster",
  "cluster_uuid" : "xASK1SUISqKRchPyg2OFFg",
  "version" : {
    "number" : "7.10.0",
    "build_flavor" : "default",
    "build_type" : "docker",
    "build_hash" : "51e9d6f22758d0374a0f3f5c6e8f3a7997850f96",
    "build_date" : "2020-11-09T21:30:33.964949Z",
    "build_snapshot" : false,
    "lucene_version" : "8.7.0",
    "minimum_wire_compatibility_version" : "6.8.0",
    "minimum_index_compatibility_version" : "6.0.0-beta1"
  },
  "tagline" : "You Know, for Search"
}

Elasticsearchにドキュメントを登録する

早速curlコマンドを使ってElasticsearchにドキュメントを登録します.
今回は以下のような形のjsonを登録してみます.

{
  "poet": "天智天皇",
  "verse": "秋の田のかりほの庵の苫をあらみ わが衣手は露にぬれつつ"
}

index名はoguraとします.

curl -XPOST -H 'Content-Type:application/json' \
-d '{"poet":"天智天皇", "verse":"秋の田のかりほの庵の苫をあらみ わが衣手は露にぬれつつ"}' \
http://localhost:9200/ogura/_doc

Elasticsearchからドキュメントを検索する

Elasticsearchに登録されているドキュメントから全文検索で取り出してみましょう.
"秋"をクエリにして検索してみましょう.

{
  "query": {"query_string": { "query": "秋" }}
}
bash
curl -XPOST -H 'Content-Type:application/json' \
-d '{"query": {"query_string": {"query": "秋"}}}' \
http://localhost:9200/ogura/_search
出力(jqで整形済み)
{
  "took": 5,
  "timed_out": false,
  "_shards": {
    "total": 1,
    "successful": 1,
    "skipped": 0,
    "failed": 0
  },
  "hits": {
    "total": {
      "value": 1,
      "relation": "eq"
    },
    "max_score": 0.2876821,
    "hits": [
      {
        "_index": "ogura",
        "_type": "_doc",
        "_id": "Au7XUXYBQ0gvhrysI8q9",
        "_score": 0.2876821,
        "_source": {
          "poet": "天智天皇",
          "verse": "秋の田のかりほの庵の苫をあらみ わが衣手は露にぬれつつ"
        }
      }
    ]
  }
}

スコアは0.2876821と低いですがヒットしていることがわかりますね.

"天皇"をクエリに検索してみましょう.

bash
curl -XPOST -H 'Content-Type:application/json' \
-d '{"query": {"query_string": {"query": "天皇"}}}' \
http://localhost:9200/ogura/_search
出力(jqで整形済み)
{
  "took": 11,
  "timed_out": false,
  "_shards": {
    "total": 1,
    "successful": 1,
    "skipped": 0,
    "failed": 0
  },
  "hits": {
    "total": {
      "value": 1,
      "relation": "eq"
    },
    "max_score": 0.68324494,
    "hits": [
      {
        "_index": "ogura",
        "_type": "_doc",
        "_id": "ZiHlUXYB-j-65sbqA5hz",
        "_score": 0.68324494,
        "_source": {
          "poet": "天智天皇",
          "verse": "秋の田のかりほの庵の苫をあらみ わが衣手は露にぬれつつ"
        }
      }
    ]
  }
}

先ほどよりも高いスコア0.68324494でヒットしていることがわかります.

おわりに

今回は全文検索エンジンのElasticsearchをDockerで立ててRESTful APIを使ってドキュメントの登録・検索をやってみました.

Elasticsearchでは前回までの記事で扱っていたMySQLと異なり非構造化データ(json)で検索対象を保存することができます.

触ってみるとRESTful APIによるインターフェースやチューニングの幅も広く,非常に優れたソフトウェアであることがわかるかと思います.