初めて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です。 ↩