ElasticSearchによる全文検索の概要

1概要

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

ElasticSearchはhttp://lucene.apache.org/core/[Ap​​ache Lucene]をベースとした無料のオープンソース情報検索ソフトウェアライブラリです。 HTTP WebインターフェースとスキーマフリーのJSON文書を備えた分散型の全文検索エンジンを提供します。

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

2セットアップ

お使いのマシンにElasticSearchをインストールするには、https://www.elastic.co/guide/en/elasticsearch/reference/current/__installation.html[公式セットアップガイド]を参照してください。

RESTfull APIはポート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 :この特定の例のtext-entryの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'

そして私達は伸縮性がある調査から次の答えを得るべきである:

{
  "__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."
  }
}

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

** 5文書の照会

**

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

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 です。

ターゲット文書に「彼」という単語が含まれているため、2番目の結果が取得されます。

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

** 6. あいまい検索

**

あいまい一致では、あいまいな2つの単語があたかも同じ単語であるかのように扱われます。第一に、私たちはあいまいさの意味を定義する必要があります。

Elasticsearchは、2のfuzzinessパラメーターで指定された最大編集距離をサポートします。fuzzinessパラメーターはAUTOに設定することができ、その結果、以下の最大編集距離が得られます。

1文字または2文字の文字列の場合は** 0

3文字、4文字、または5文字のストリングの場合は** 1

5文字を超える文字列の場合は** 2

編集距離 2 を指定すると、関連性がないと思われる結果が返されることがあります。

最大のあいまいさは1で、より良い結果とパフォーマンスが得られます。距離とは、2つのシーケンス間の差を測定するための文字列メトリックであるLevenshtein距離のことです。

非公式には、2つの単語間のhttps://en.wikipedia.org/wiki/Levenshtein__distance[Levenshtein距離]は、1文字の編集の最小数です。

あいまい検索を実行しましょう。

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. 結論

このクイックチュートリアルでは、ドキュメントのインデックス作成と全文検索のためのElasticsearchへのクエリをREST APIから直接行いました。

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

前の投稿:Spring Security - キャッシュコントロールヘッダ
次の投稿:ScribeJavaへのガイド