结合bool和范围查询,弹性搜索的难度

时间:2016-05-10 15:05:58

标签: elasticsearch querydsl

我在理解弹性搜索中嵌套查询的各种方法时遇到了一些麻烦。以下是我的索引数据的示例..

{
    "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 个答案:

答案 0 :(得分:7)

您的范围查询必须在must子句中:

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

您将不同的查询与bool查询结合使用。它需要4个不同的条款:mustshouldnot_mustfilter

filtermust相同。差异是过滤器的得分不计算。

基本结构(取自doc):

{
    "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" }
            }
        ]
    }
}