1. 概要

全文検索は、ドキュメントに対してクエリを実行し、言語検索を実行します。 単一または複数の単語またはフレーズが含まれ、検索条件に一致するドキュメントを返します。

ElasticSearchは、無料のオープンソース情報検索ソフトウェアライブラリである ApacheLuceneに基づく検索エンジンです。 HTTPWebインターフェイスとスキーマフリーのJSONドキュメントを備えた分散型全文検索エンジンを提供します。

この記事では、ElasticSearch REST APIを検証し、HTTPリクエストのみを使用した基本的な操作について説明します。

2. 設定

お使いのマシンにElasticSearchをインストールするには、公式セットアップガイドを参照してください。

RESTfullAPIはポート9200で実行されます。 次のcurlコマンドを使用して、正しく実行されているかどうかをテストしてみましょう。

curl -XGET 'http://localhost:9200/'

次の応答を確認すると、インスタンスは正しく実行されています。

{
  "name": "NaIlQWU",
  "cluster_name": "elasticsearch",
  "cluster_uuid": "enkBkWqqQrS0vp_NXmjQMQ",
  "version": {
    "number": "5.1.2",
    "build_hash": "c8c4c16",
    "build_date": "2017-01-11T20:18:39.146Z",
    "build_snapshot": false,
    "lucene_version": "6.3.0"
  },
  "tagline": "You Know, for Search"
}

3. ドキュメントのインデックス作成

ElasticSearchはドキュメント指向です。 ドキュメントを保存してインデックスを作成します。 インデックス作成は、ドキュメントを作成または更新します。 インデックスを作成した後、列データの行ではなく、完全なドキュメントを検索、並べ替え、およびフィルタリングできます。 これはデータについての根本的に異なる考え方であり、ElasticSearchが複雑な全文検索を実行できる理由の1つです。

ドキュメントはJSONオブジェクトとして表されます。 JSONシリアル化は、ほとんどのプログラミング言語でサポートされており、NoSQLムーブメントで使用される標準形式になっています。 シンプルで簡潔、そして読みやすいです。

次のランダムなエントリを使用して、全文検索を実行します。

{
  "title": "He went",
  "random_text": "He went such dare good fact. The small own seven saved man age."
}

{
  "title": "He oppose",
  "random_text": 
    "He oppose at thrown desire of no. \
      Announcing impression unaffected day his are unreserved indulgence."
}

{
  "title": "Repulsive questions",
  "random_text": "Repulsive questions contented him few extensive supported."
}

{
  "title": "Old education",
  "random_text": "Old education him departure any arranging one prevailed."
}

ドキュメントにインデックスを付ける前に、ドキュメントを保存する場所を決定する必要があります。 複数のインデックスを持つことができ、そのインデックスには複数のタイプが含まれます。 これらのタイプは複数のドキュメントを保持し、各ドキュメントには複数のフィールドがあります。

次のスキームを使用してドキュメントを保存します。

text :インデックス名。 article :タイプ名。 id :この特定の例のテキストエントリのID。

ドキュメントを追加するには、次のコマンドを実行します。

curl -XPUT 'localhost:9200/text/article/1?pretty'
  -H 'Content-Type: application/json' -d '
{
  "title": "He went",
  "random_text": 
    "He went such dare good fact. The small own seven saved man age."
}'

ここではid= 1 を使用していますが、同じコマンドとインクリメントされたidを使用して他のエントリを追加できます。

4. ドキュメントの取得

すべてのドキュメントを追加したら、次のコマンドを使用して、クラスター内にあるドキュメントの数を確認できます。

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

また、次のコマンドでIDを使用してドキュメントを取得できます。

curl -XGET 'localhost:9200/text/article/1?pretty'

そして、elasticsearchから次の答えを得る必要があります。

{
  "_index": "text",
  "_type": "article",
  "_id": "1",
  "_version": 1,
  "found": true,
  "_source": {
    "title": "He went",
    "random_text": 
      "He went such dare good fact. The small own seven saved man age."
  }
}

ご覧のとおり、この回答はID1を使用して追加されたエントリに対応しています。

5. ドキュメントのクエリ

OK、次のコマンドで全文検索を実行しましょう。

curl -XGET 'localhost:9200/text/article/_search?pretty' 
  -H 'Content-Type: application/json' -d '
{
  "query": {
    "match": {
      "random_text": "him departure"
    }
  }
}'

そして、次の結果が得られます。

{
  "took": 32,
  "timed_out": false,
  "_shards": {
    "total": 5,
    "successful": 5,
    "failed": 0
  },
  "hits": {
    "total": 2,
    "max_score": 1.4513469,
    "hits": [
      {
        "_index": "text",
        "_type": "article",
        "_id": "4",
        "_score": 1.4513469,
        "_source": {
          "title": "Old education",
          "random_text": "Old education him departure any arranging one prevailed."
        }
      },
      {
        "_index": "text",
        "_type": "article",
        "_id": "3",
        "_score": 0.28582606,
        "_source": {
          "title": "Repulsive questions",
          "random_text": "Repulsive questions contented him few extensive supported."
        }
      }
    ]
  }
}

ご覧のとおり、「彼の出発」を探しており、スコアの異なる2つの結果が得られます。 最初の結果は明らかです。テキスト内に検索が実行されており、ご覧のとおり、スコアは1.4513469です。

ターゲットドキュメントに「him」という単語が含まれているため、2番目の結果が取得されます。

デフォルトでは、ElasticSearchは、関連性スコア、つまり各ドキュメントがクエリとどの程度一致しているかによって、一致する結果を並べ替えます。 2番目の結果のスコアは最初のヒットに比べて小さく、関連性が低いことを示していることに注意してください。

6. あいまい検索

ファジーマッチングは、「あいまいに」類似している2つの単語を同じ単語であるかのように扱います。 まず、あいまいさの意味を定義する必要があります。

Elasticsearchは、ファジーパラメーターで指定された最大編集距離2をサポートします。 ファジーパラメータはAUTOに設定できます。これにより、次の最大編集距離が得られます。

  • 01文字または2文字の文字列の場合
  • 1 3、4、または5文字の文字列の場合
  • 25文字を超える文字列の場合

2 の編集距離では、関連していないように見える結果が返される場合があります。

最大ファジー1で、より良い結果とより良いパフォーマンスが得られる場合があります。 距離とは、2つのシーケンス間の差を測定するための文字列メトリックであるレーベンシュタイン距離を指します。 非公式には、2つの単語間のレーベンシュタイン距離は、1文字の編集の最小数です。

OK、あいまいな状態で検索を実行しましょう。

curl -XGET 'localhost:9200/text/article/_search?pretty' -H 'Content-Type: application/json' -d' 
{ 
  "query": 
  { 
    "match": 
    { 
      "random_text": 
      {
        "query": "him departure",
        "fuzziness": "2"
      }
    } 
  } 
}'

結果は次のとおりです。

{
  "took": 88,
  "timed_out": false,
  "_shards": {
    "total": 5,
    "successful": 5,
    "failed": 0
  },
  "hits": {
    "total": 4,
    "max_score": 1.5834423,
    "hits": [
      {
        "_index": "text",
        "_type": "article",
        "_id": "4",
        "_score": 1.4513469,
        "_source": {
          "title": "Old education",
          "random_text": "Old education him departure any arranging one prevailed."
        }
      },
      {
        "_index": "text",
        "_type": "article",
        "_id": "2",
        "_score": 0.41093433,
        "_source": {
          "title": "He oppose",
          "random_text":
            "He oppose at thrown desire of no. 
              \ Announcing impression unaffected day his are unreserved indulgence."
        }
      },
      {
        "_index": "text",
        "_type": "article",
        "_id": "3",
        "_score": 0.2876821,
        "_source": {
          "title": "Repulsive questions",
          "random_text": "Repulsive questions contented him few extensive supported."
        }
      },
      {
        "_index": "text",
        "_type": "article",
        "_id": "1",
        "_score": 0.0,
        "_source": {
          "title": "He went",
          "random_text": "He went such dare good fact. The small own seven saved man age."
        }
      }
    ]
  }
}'

ご覧のとおり、あいまいさはより多くの結果をもたらします。

あいまいさは無関係に見える結果を取得する傾向があるため、慎重に使用する必要があります。

7. 結論

このクイックチュートリアルでは、REST API を介して、ドキュメントのインデックス作成と全文検索のためのElasticsearchのクエリに焦点を当てました。

もちろん、必要に応じて複数のプログラミング言語で利用できるAPIを用意していますが、APIは依然として非常に便利で、言語に依存しません。