Search code examples
elasticsearchelasticsearch-dslelasticsearch-dsl-py

How to compound terms query and bool query together in Elasticsearch


Originally, I would add a filter in the bool query. However, when I turn to terms filter, the documents indicates that it should be replaced by terms query now. So I understand this as that we need to construct a compound query with both terms query and bool query. If I am correct, how should I write the query?

Note: I use elasticsearch's Python API.


Solution

  • There are two types of context now: query context and filter context. Any query clause inside query context contribute to the score of matching document i.e. how well a document matched a query whereas any query clause inside filter context determines whether or not the document matches and doesn't contribute to the score.

    So in the query below I have marked both the contexts:

    {
      "query": { 
        "bool": { 
          "must": [
            { "match": { "field1":   "terms1"}},              <------query context
          ],
          "filter": [ 
            { "terms":  { "someId": [3242, 12343, 1234] }},   <-------inside filter block every query clause will act as filter (filter context)
          ]
        }
      }
    }
    

    Therefore in order to use terms query as a filter you need to follow the below steps:

    1. Create a bool query say boolQuery
    2. Create a terms query sat termsQuery
    3. Add termsQuery to filter of boolQuery.
    4. Set boolQuery as query.

    This translates to below:

    {
      "query": {
        "bool": {
          "filter": [
            {
              "terms": {
                "field1": ["terms1", "term2", "terms3"]
              }
            }
          ]
        }
      }
    }