1
2

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 3 years have passed since last update.

【Elasticsearch入門】速習Elasticsearch Search query Boolクエリ編

Last updated at Posted at 2020-07-28

ゴール

本記事ではElasticsearchの以下の基本操作の中のSearch queryの中の基本クエリ(match_phrase, multi_match)を簡単に紹介します
※最初の方のパートはElasticsearchの説明やデータの準備パートとなっているため 【Elasticsearch入門】速習Elasticsearch Search query 基本クエリ(match, match_all)編と内容が被っているので読み飛ばしても構いません。

  • CRUD
  • Search
    • query
      • 基本クエリ
      • Termクエリ
      • Boolクエリ
        • must
        • should
        • must_not
        • filter
    • aggregation

Elasticsearch

Elasticsearch は オープンソースの全文検索エンジンです。
Apache LuceneをベースとしたJavaで書かれたソフトウェアでElastic社により開発が進められています。
登録したドキュメントから目的の単語を含むドキュメントを高速に検索することができます。
基本的にElasticsearchではRestful APIを使って操作します。

バージョン等

Elasticsearch: 7.6.2
kibana: 7.6.2
※ 簡単にSearch queryの操作を行うためにKibanaのDevToolsを使用します。

環境準備

環境に関しては以下の投稿に記載の通りで用意しています。
【Elasticsearch入門】環境構築
【Elasticsearch入門】環境構築 Windows編

準備

サンプルデータの用意をしていきます。

ecommerceデータ

Kibanaの初期画面で「Add sample data」を選択してください。
image.png
以下の画面に遷移するので一番左の「Sample eCommerce orders」の「Add data」を押下してください。
image.png
そうするとサンプルデータが用意されます。
Dev Toolsに移動して以下のクエリを投げてください。

GET kibana_sample_data_ecommerce/_search

レスポンスによりデータがあることが確認できると思います。

自作データ

KibanaでDev Toolsに移動して以下のクエリを実行して5つのドキュメントがあるインデックスを作成してください。
(ちなみにこれらのcontentの内容はElasticsearchの公式ドキュメントに記載されているものです。時間があれば読んでみてください。勉強になります。)

PUT my_index/_doc/1
{
  "title": "Elasticsearch",
  "content": "Elasticsearch is the distributed search and analytics engine at the heart of the Elastic Stack. Logstash and Beats facilitate collecting, aggregating, and enriching your data and storing it in Elasticsearch. Kibana enables you to interactively explore, visualize, and share insights into your data and manage and monitor the stack. Elasticsearch is where the indexing, search, and analysis magic happens."
}

PUT my_index/_doc/2
{
  "title": "Kibana",
  "content": "Elasticsearch is the distributed search and analytics engine at the heart of the Elastic Stack. Logstash and Beats facilitate collecting, aggregating, and enriching your data and storing it in Elasticsearch. Kibana enables you to interactively explore, visualize, and share insights into your data and manage and monitor the stack. Elasticsearch is where the indexing, search, and analysis magic happens."
}

PUT my_index/_doc/3
{
  "title": "Elasticsearch",
  "content": "While not every problem is a search problem, Elasticsearch offers speed and flexibility to handle data in a wide variety of use cases:"
}

PUT my_index/_doc/4
{
  "title": "Kibana",
  "content": "While not every problem is a search problem, Elasticsearch offers speed and flexibility to handle data in a wide variety of use cases:"
}

PUT my_index/_doc/5
{
  "title": "Elastic Stack",
  "content": "While not every problem is a search problem, Elasticsearch offers speed and flexibility to handle data in a wide variety of use cases:"
}

以下のクエリでインデックスが作成できたことを確認してください。

GET my_index/_search

確認ができたらBoolクエリを使ってみましょう。

クエリの紹介

Boolクエリ

Boolクエリは基本クエリを複数組み合わせて複合クエリのように扱うクエリとなります。

基本構文

GET my_index/_search
{
  "query": {
    "bool": {
      "must": [ <基本クエリ>, <基本クエリ>,,, ],
      "should": [ <基本クエリ>, <基本クエリ>,,, ],
      "must_not": [ <基本クエリ>, <基本クエリ>,,, ],
      "filter": [ <基本クエリ>, <基本クエリ>,,, ]
    }
  }
}

上記のようにbool句の中に, must, should, must_not, filterの4種類の句を自由に組み合わせることができます。

must句

must句では必ず含まれているべき条件を指定します。
複数の基本クエリを指定した場合は条件が全て満たされる必要があります。


リクエスト

GET my_index/_search
{
  "query": {
    "bool": {
      "must": [
        {"match": {"title": "Elasticsearch"}},
        {"match": {"content": "problem"}}
      ]
    }
  }
}

レスポンス

{
  "took" : 6,
  "timed_out" : false,
  "_shards" : {
    "total" : 1,
    "successful" : 1,
    "skipped" : 0,
    "failed" : 0
  },
  "hits" : {
    "total" : {
      "value" : 1,
      "relation" : "eq"
    },
    "max_score" : 1.7706487,
    "hits" : [
      {
        "_index" : "my_index",
        "_type" : "_doc",
        "_id" : "3",
        "_score" : 1.7706487,
        "_source" : {
          "title" : "Elasticsearch",
          "content" : "While not every problem is a search problem, Elasticsearch offers speed and flexibility to handle data in a wide variety of use cases:"
        }
      }
    ]
  }
}

レスポンスをみるとtitleElasticsearch, contentproblemがマッチするものが引っかかっていることがわかると思います。

should句

shouldの中に複数の基本クエリを指定した場合、いずれかの条件を満たせばドキュメントが引っかかります。
つまり、OR検索と同じ意味になります。


リクエスト

GET my_index/_search
{
  "query": {
    "bool": {
      "should": [
        {"match": {"title": "elasticsearch"}},
        {"match": {"content": "problem"}}
      ]
    }
  }
}

レスポンス

{
  "took" : 4,
  "timed_out" : false,
  "_shards" : {
    "total" : 1,
    "successful" : 1,
    "skipped" : 0,
    "failed" : 0
  },
  "hits" : {
    "total" : {
      "value" : 4,
      "relation" : "eq"
    },
    "max_score" : 1.7706487,
    "hits" : [
      {
        "_index" : "my_index",
        "_type" : "_doc",
        "_id" : "3",
        "_score" : 1.7706487,
        "_source" : {
          "title" : "Elasticsearch",
          "content" : "While not every problem is a search problem, Elasticsearch offers speed and flexibility to handle data in a wide variety of use cases:"
        }
      },
      {
        "_index" : "my_index",
        "_type" : "_doc",
        "_id" : "1",
        "_score" : 0.9395274,
        "_source" : {
          "title" : "Elasticsearch",
          "content" : "Elasticsearch is the distributed search and analytics engine at the heart of the Elastic Stack. Logstash and Beats facilitate collecting, aggregating, and enriching your data and storing it in Elasticsearch. Kibana enables you to interactively explore, visualize, and share insights into your data and manage and monitor the stack. Elasticsearch is where the indexing, search, and analysis magic happens."
        }
      },
      {
        "_index" : "my_index",
        "_type" : "_doc",
        "_id" : "4",
        "_score" : 0.8311213,
        "_source" : {
          "title" : "Kibana",
          "content" : "While not every problem is a search problem, Elasticsearch offers speed and flexibility to handle data in a wide variety of use cases:"
        }
      },
      {
        "_index" : "my_index",
        "_type" : "_doc",
        "_id" : "5",
        "_score" : 0.8311213,
        "_source" : {
          "title" : "Elastic Stack",
          "content" : "While not every problem is a search problem, Elasticsearch offers speed and flexibility to handle data in a wide variety of use cases:"
        }
      }
    ]
  }
}

レスポンスをみるとtitleElasticsearch, contentproblemのいずれかがマッチするものが引っかかっていることがわかると思います。

また、【Elasticsearch入門】速習Elasticsearch Search query 基本クエリ(match, match_all)編でも紹介したminimum_should_matchをこちらでも利用できます。
こちらはshould句の中に「指定した複数条件のうち、最低N個以上の条件をみたす。」という使い方をできます。

以下のような使い方となります。

GET my_index/_search
{
  "query": {
    "bool": {
      "should": [
        {"match": {"title": "elasticsearch"}},
        {"match": {"content": "problem"}},
        {"match": {"content": "data"}}
      ],
      "minimum_should_match": 2
    }
  }
}

must_not句

must_not句の中に指定した基本クエリに当てはまるものは検索結果から除外されます。
つまり、should句の否定となります。


リクエスト

GET my_index/_search
{
  "query": {
    "bool": {
      "must_not": [
        {"match": {"title": "elasticsearch"}},
        {"match": {"content": "problem"}}
      ]
    }
  }
}

レスポンス

{
  "took" : 0,
  "timed_out" : false,
  "_shards" : {
    "total" : 1,
    "successful" : 1,
    "skipped" : 0,
    "failed" : 0
  },
  "hits" : {
    "total" : {
      "value" : 1,
      "relation" : "eq"
    },
    "max_score" : 0.0,
    "hits" : [
      {
        "_index" : "my_index",
        "_type" : "_doc",
        "_id" : "2",
        "_score" : 0.0,
        "_source" : {
          "title" : "Kibana",
          "content" : "Elasticsearch is the distributed search and analytics engine at the heart of the Elastic Stack. Logstash and Beats facilitate collecting, aggregating, and enriching your data and storing it in Elasticsearch. Kibana enables you to interactively explore, visualize, and share insights into your data and manage and monitor the stack. Elasticsearch is where the indexing, search, and analysis magic happens."
        }
      }
    ]
  }
}

レスポンスをみるとtitleElasticsearch, contentproblemのどちらともマッチしないものが引っかかっていることがわかると思います。
また、should句の結果と合わせると一つのインデックスになっているのもわかるかと思います。

filter句

最後はfilter句です。
filter句の特徴はこれまで紹介してきた句の特徴と少し異なります。
今までの句では検索条件の関連度に基づきスコアが返却されます。
一方でfilter句は検索条件にマッチするかしないかのみが返されます。
(これらの違いによる「Queryコンテキスト」、「Filterコンテキスト」という分類がある)


リクエスト

GET kibana_sample_data_ecommerce/_search
{
  "query": {
    "bool": {
      "must": [
        {"match": {"products.product_name": "shirt"}}
      ],
      "filter": [
        {"range": 
          {
            "taxful_total_price": {
              "gte": 10,
              "lte": 20
            } 
          }
        }
      ]
    }
  }
}

レスポンス

...
 {
        "_index" : "kibana_sample_data_ecommerce",
        "_type" : "_doc",
        "_id" : "3p4NgHMBFnhBnJdY3gCV",
        "_score" : 1.8671052,
        "_source" : {
          "category" : [
            "Men's Clothing"
          ],
          "currency" : "EUR",
          "customer_first_name" : "Sultan Al",
          "customer_full_name" : "Sultan Al Richards",
          "customer_gender" : "MALE",
          "customer_id" : 19,
          "customer_last_name" : "Richards",
          "customer_phone" : "",
          "day_of_week" : "Saturday",
          "day_of_week_i" : 5,
          "email" : "sultan al@richards-family.zzz",
          "manufacturer" : [
            "Elitelligence",
            "Low Tide Media"
          ],
          "order_date" : "2020-08-01T02:42:43+00:00",
          "order_id" : 581482,
          "products" : [
            {
              "base_price" : 7.99,
              "discount_percentage" : 0,
              "quantity" : 1,
              "manufacturer" : "Elitelligence",
              "tax_amount" : 0,
              "product_id" : 11389,
              "category" : "Men's Clothing",
              "sku" : "ZO0562105621",
              "taxless_price" : 7.99,
              "unit_discount_amount" : 0,
              "min_price" : 3.6,
              "_id" : "sold_product_581482_11389",
              "discount_amount" : 0,
              "created_on" : "2016-12-24T02:42:43+00:00",
              "product_name" : "Basic T-shirt - green",
              "price" : 7.99,
              "taxful_price" : 7.99,
              "base_unit_price" : 7.99
            },
            {
              "base_price" : 11.99,
              "discount_percentage" : 0,
              "quantity" : 1,
              "manufacturer" : "Low Tide Media",
              "tax_amount" : 0,
              "product_id" : 17390,
              "category" : "Men's Clothing",
              "sku" : "ZO0438604386",
              "taxless_price" : 11.99,
              "unit_discount_amount" : 0,
              "min_price" : 5.4,
              "_id" : "sold_product_581482_17390",
              "discount_amount" : 0,
              "created_on" : "2016-12-24T02:42:43+00:00",
              "product_name" : "Print T-shirt - multicoloured",
              "price" : 11.99,
              "taxful_price" : 11.99,
              "base_unit_price" : 11.99
            }
          ],
          "sku" : [
            "ZO0562105621",
            "ZO0438604386"
          ],
          "taxful_total_price" : 19.98,
          "taxless_total_price" : 19.98,
          "total_quantity" : 2,
          "total_unique_products" : 2,
          "type" : "order",
          "user" : "sultan",
          "geoip" : {
            "country_iso_code" : "AE",
            "location" : {
              "lon" : 54.4,
              "lat" : 24.5
            },
            "region_name" : "Abu Dhabi",
            "continent_name" : "Asia",
            "city_name" : "Abu Dhabi"
          }
        }
      }
...

上記は「10ユーロから20ユーロの間でトータルの支払いをした客でシャツを買った客」の検索結果を示しています。10ユーロから20ユーロの間でフィルターがかけられてその中からproducts.product_nameshirtとマッチするものが検索されています。

フィルタのメリットとしてクエリキャッシュというキャッシュ機能があります。
スコアに関連した検索でなく単に検索範囲を限定したい時、フィルタクエリを使うことで性能向上ができます。
フィルタクエリでは検索結果をキャッシュして保持するため、一度検索されると高速に結果を返すことができます。
是非使ってみてください。

以上でboolクエリの解説を終わります。

おすすめ教材

1
2
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
1
2

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?