LoginSignup
218
201

More than 5 years have passed since last update.

Elasticsearchのbool queryを利用してAND OR NOTを書いてみる

Last updated at Posted at 2016-04-25

初めてElasticsearchのクエリをビルドしたのでいろいろハマりました。SQLの世界観とちょっと違っていて、なれるまで時間がかかると思います。でも、なれたら複雑な検索条件をSQLより簡単に書けるかも知れません。

では、Elasticsearchの基礎クエリの一つ、Bool Queryを解説してみます。

Bool Queryについて

Elasticsearch 2.0からandクエリorクエリは全部非推奨になり、その代わりにboolクエリの方が推奨されます。Boolクエリは複数のクエリを組み合わせる(つまりAND、OR、NOTで結合)のに使います。

Boolクエリは4種類があります:must、 filter、 should、 must_notです。

クエリ 説明
must ANDとして使います。小クエリは総合スコアに影響を与えます
filter mustと同じくANDです。ただし、スコアは無視されます(総合スコアに影響を与えません)。
should ORとして使えます。 minimum_should_matchパラメータで最低マッチする条項の数が指定できます1
must_not NOTです。

使用例

AND条件

例えば、SQLはこういうSELECT文があります。

SELECT * FROM users WHERE age >= 25 AND salary >= 500000;

Elasticsearchのクエリに書き直すと、

{
  "query": {
    "bool" : {
      "must" : [
        { "range" : { "age" : { "gte": 25 } } },
        { "range" : { "salary" : { "gte": 500000  } } }
      ]
    }
  }
}

になります。今回はmustを使いますが、スコア無視したい場合はfilterを使えばいいのです。

OR条件

SELECT * FROM users WHERE age >= 25 OR salary >= 500000;

Elasticsearchのクエリに書き直すと、

{
  "query": {
    "bool" : {
      "should" : [
        { "range" : { "age" : { "gte": 25 } } },
        { "range" : { "salary" : { "gte": 500000  } } }
      ],
      "minimum_should_match" : 1
    }
  }
}

になります。

NOT条件

SELECT * FROM users WHERE user_id NOT BETWEEN 525 AND 600;

Elasticsearchのクエリに書き直すと、

{
  "query": {
    "bool" : {
      "must_not" : {
        "range" : { "user_id" : { "gte": 525, "lte": 600  } }
      }
    }
  }
}

になります。

AND、OR、NOTを組み合わせてみる

SELECT * FROM users WHERE (salary >= 500000 AND status = 'active')
                      OR (user_id NOT BETWEEN 525 AND 600);

Elasticsearchのクエリに書き直すと、

{
  "query": {
    "bool" : {
      "should" : [
         { 
           "bool" : {
             "must": [
               { "range": { "salary" : { "gte": 500000 } } },
               { "term": {"status": "active" } }
             ]
           } 
         },
         {
           "bool": {
             "must_not" : {
               "range" : { "user_id" : { "gte": 525, "lte": 600 } } 
             }
           }
         } 
       ]
    }
  }
}

になります。

注意したいのはboolクエリはネストができるため、いくら複雑な条件にしても表現できます。

まとめ

条件 SQL Elasticsearch
AND WHERE A AND B {"bool": {"must": [A,B]}
OR WHERE A OR B {"bool": {"should": [A,B]}
NOT WHERE NOT A {"bool": {"must_not": A}

おまけ

Elasticsearchクエリはポーランド記法と似ていますね。
例えば、3+4だったら+ 3 4になり、(1 + 5) * (2 + 3)だったら(* (+ 1 5) (+ 2 3))になりますね。なかなか面白いです!

では、よいサーチライフを!

参考文献


  1. 公式ドキュメントには書いてないがおそらくデフォルト値は1です。 

218
201
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
218
201