Сложность, сочетающая бул и диапазон запроса, упругий поиск

У меня возникли проблемы с пониманием различных способов вложения запросов в упругий поиск. Вот пример того, как мои индексированные данные выглядят..

{
    "Underlying" : "Eurodollar",
    "Expiration" : "20160315"
},
{
    "Underlying" : "Eurodollar",
    "Expiration" : "20160415"
},
{
    "Underlying" : "Eurodollar",
    "Expiration" : "20160515"
}

Итак, я смог выполнить запрос как этот

{
    "query" : {
        "range" : {
            "Expiration" : {
                "gte" : "20160315",
                "lte" : "20160515"
            }
        }
    }
}

И, как и ожидалось, я получаю все записи. ОДНАКО, предположим, я также проиндексировал такие записи.

{
   "Underlying" : "Something else",
   "Expiration" : "20160415"
}

Я не хочу, чтобы результаты "Что-то еще" возвращались, поэтому сейчас я пытаюсь сделать что-то подобное.

{
    "query" : {
        "bool" : {
            "must" : [
                {
                    "term" : {
                        "Underlying" : {
                            "value" : "eurodollar"
                        }
                    }
                }
            ]
        },
        "range" : {
            "Expiration" : {
                "gte" : "20160315",
                "lte" : "20160515"
            }
        }
    }
}

Но я получаю ошибку

RequestError(400, u'SearchPhaseExecutionException[Failed to execute phase [query], all shards failed; shardFailures {[cCrh939sR7yHdKgawRi6Sw][test-index][0]: SearchParseException[[test-index][0]: query[Expiration:[20160215 TO 20160415]],from[-1],size[-1]: Parse Failure [Failed to parse source [{"query": {"range": {"Expiration": {"gte": "20160215", "lte": "20160415"}}, "bool": {"must": [{"term": {"Underlying": {"value": "eurodollar"}}}]}}}]]]; nested: ElasticsearchParseException[Expected field name but got START_OBJECT "bool"]; }{[cCrh939sR7yHdKgawRi6Sw][test-index][1]: SearchParseException[[test-index][1]: query[Expiration:[20160215 TO 20160415]],from[-1],size[-1]: Parse Failure [Failed to parse source [{"query": {"range": {"Expiration": {"gte": "20160215", "lte": "20160415"}}, "bool": {"must": [{"term": {"Underlying": {"value": "eurodollar"}}}]}}}]]]; nested: ElasticsearchParseException[Expected field name but got START_OBJECT "bool"]; }]', {u'status': 400, u'error': u'SearchPhaseExecutionException[Failed to execute phase [query], all shards failed; shardFailures {[cCrh939sR7yHdKgawRi6Sw][test-index][0]: SearchParseException[[test-index][0]: query[Expiration:[20160215 TO 20160415]],from[-1],size[-1]: Parse Failure [Failed to parse source [{"query": {"range": {"Expiration": {"gte": "20160215", "lte": "20160415"}}, "bool": {"must": [{"term": {"Underlying": {"value": "eurodollar"}}}]}}}]]]; nested: ElasticsearchParseException[Expected field name but got START_OBJECT "bool"]; }{[cCrh939sR7yHdKgawRi6Sw][test-index][1]: SearchParseException[[test-index][1]: query[Expiration:[20160215 TO 20160415]],from[-1],size[-1]: Parse Failure [Failed to parse source [{"query": {"range": {"Expiration": {"gte": "20160215", "lte": "20160415"}}, "bool": {"must": [{"term": {"Underlying": {"value": "eurodollar"}}}]}}}]]]; nested: ElasticsearchParseException[Expected field name but got START_OBJECT "bool"]; }]'})

Наиболее актуальный текст ошибки, кажется, это

 Expected field name but got START_OBJECT "bool"

Я знаю, что мой запрос bool / term работает, потому что я запустил только это

{
    "query" : {
        "bool" : {
            "must" : [
                {
                    "term" : {
                        "Underlying" : {
                            "value" : "eurodollar"
                        }
                    }
                }
            ]
        }
    }
}

И я получил ожидаемые результаты.

Я думаю, что это достаточно хорошо иллюстрирует мою ситуацию. Как правильно объединить эти запросы, учитывая, что мое предположение о том, как они должны быть объединены, неверно.

1 ответ

Решение

Ваш запрос диапазона должен быть внутри предложения must:

{
    "query" : {
        "bool" : {
            "must" : [
                {
                    "term" : {
                        "Underlying" : {
                            "value" : "eurodollar"
                        }
                    }
                },
                {
                     "range" : {
                        "Expiration" : {
                            "gte" : "20160315",
                            "lte" : "20160515"
                        }
                     }
                 } 
            ]
        }
    }
}

Вы комбинируете разные запросы с bool запрос. И это займет 4 разных пункта в нем: must, should, not_must а также filter,

filter такой же как must, Разница в баллах за фильтр не учитывается.

И основная структура (взята из документа):

{
    "bool" : {
        "must" : {
            "term" : { "user" : "kimchy" }
        },
        "filter": {
            "term" : { "tag" : "tech" }
        },
        "must_not" : {      <= single inside query
            "range" : {
                "age" : { "from" : 10, "to" : 20 }
            }
        },
        "should" : [        <= that is an array
            {               <= start of inner query is important
                "term" : { "tag" : "wow" }
            },
            {
                "term" : { "tag" : "elasticsearch" }
            }
        ]
    }
}
Другие вопросы по тегам