Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Difficulty combining bool and range query, elastic search

I'm having a bit of trouble understanding the various ways to nest queries in elastic search. Here is an example of what my indexed data looks like..

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

So, I was able to run a query like this

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

And as expected, I get all entries. HOWEVER, suppose I ALSO have indexed entries like this.

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

I don't want the "Something else" results to come back, so I now attempt to do something like this.

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

But I am getting an error

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"]; }]'})

The most relevant text of the error seems to be this

 Expected field name but got START_OBJECT "bool"

I know my bool/term query is working, because I ran just this

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

And I got back the expected results.

I think this illustrates my situation well enough. How do I properly combine these queries, given that my guess as to how they should be combined is incorrect.

like image 783
Zack Avatar asked May 10 '16 15:05

Zack


1 Answers

Your range query must be inside the must clause:

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

You combine different queries with bool query. And it take 4 different clause in it: must, should, not_must and filter.

filter is same as must. Difference is score for filter is not counted.

And basic structure is (taken from 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" }
      }
    ]
  }
}
like image 112
alpert Avatar answered Oct 16 '22 18:10

alpert