Here you go,
{
"query": {
"bool": {
"must": [
{
"term": {
"category": "foo"
}
},
{
"term": {
"name": "bar"
}
},
{
"bool": {
"should": [
{
"bool": {
"must": [
{
"term": {
"x": 1
}
},
{
"term": {
"y": 2
}
},
{
"term": {
"z": 3
}
}
]
}
},
{
"bool": {
"must": [
{
"term": {
"x": 4
}
},
{
"term": {
"y": 5
}
},
{
"term": {
"z": 6
}
}
]
}
},
{
"bool": {
"must": [
{
"term": {
"x": 7
}
},
{
"term": {
"y": 8
}
},
{
"term": {
"z": 9
}
}
]
}
}
]
}
}
]
}
}
}
All you need is [bool][1] query, with a combination of `must` and `should` clauses.
[1]: https://www.elastic.co/guide/en/elasticsearch/reference/current/query-dsl-bool-query.html
I finally managed to create a query that does exactly what i wanted to have:
A filtered nested boolean query.
I am not sure why this is not documented. Maybe someone here can tell me?
Here is the query:
GET /test/object/_search
{
"from": 0,
"size": 20,
"sort": {
"_score": "desc"
},
"query": {
"filtered": {
"filter": {
"bool": {
"must": [
{
"term": {
"state": 1
}
}
]
}
},
"query": {
"bool": {
"should": [
{
"bool": {
"must": [
{
"match": {
"name": "foo"
}
},
{
"match": {
"name": "bar"
}
}
],
"should": [
{
"match": {
"has_image": {
"query": 1,
"boost": 100
}
}
}
]
}
},
{
"bool": {
"must": [
{
"match": {
"info": "foo"
}
},
{
"match": {
"info": "bar"
}
}
],
"should": [
{
"match": {
"has_image": {
"query": 1,
"boost": 100
}
}
}
]
}
}
],
"minimum_should_match": 1
}
}
}
}
}
In pseudo-SQL:
SELECT * FROM /test/object
WHERE
((name=foo AND name=bar) OR (info=foo AND info=bar))
AND state=1
Please keep in mind that it depends on your document field analysis and mappings how name=foo is internally handled. This can vary from a fuzzy to strict behavior.
"minimum_should_match": 1 says, that at least one of the should statements must be true.
This statements means that whenever there is a document in the resultset that contains has_image:1 it is boosted by factor 100. This changes result ordering.
"should": [
{
"match": {
"has_image": {
"query": 1,
"boost": 100
}
}
}
]
Have fun guys :)