1
votes

I'm creating filtering queries which operates on two fields. I would like to avoid computing relevance by Elasticsearch. How to achieve OR statement without moving to query context.

My simplified model has two boolean fields:

{
   is_opened,
   is_send
}

I'd like to prepare query with logic:

(is_opened == true AND is_send == true) OR (is_opened == false) 

In other words I want to exclude documents with fields:

is_opened == true AND is_send == false

My query looks like that:

GET documents/default/_search
{
  "query": {
    "bool": {
      "should": [
        {
          "bool":{
            "must":[
                {"term": {"is_opened":true}},
                {"term": {"is_send":true}}
              ]
          }
        },
        {
          "bool":{
            "must":[
                {"term": {"is_opened":false}}
              ]
          }
        }
      ]
    }
  }
}

Logically it works as I expected but Elasticsearch computes relevance. I don't need it because at the end I sort results by another field so it's a place to optimize queries. I ask about it because Frequently used filters will be cached automatically by Elasticsearch, to speed up performance.

My results have _score field computed so I think that above query is executed in query context so Elasticsearch won't cache it automatically.

In the future I would like to create queries which operates on status fields, where logic would be more complicated. Still I need to know how to block computing _score.

I noticed that changing should to filter block computing _score but works as must operator. Is it possible to change filter behavior?

Is it possible to use another query than should? How to force Elasticserach to stop computing _score?

1

1 Answers

2
votes

Simply wrap your query inside the constant_score query:

GET documents/default/_search
{
  "query": {
    "constant_score": {
      "filter": {
        "bool": {
          "should": [
            {
              "bool": {
                "must": [
                  {
                    "term": {
                      "is_opened": true
                    }
                  },
                  {
                    "term": {
                      "is_send": true
                    }
                  }
                ]
              }
            },
            {
              "bool": {
                "must": [
                  {
                    "term": {
                      "is_opened": false
                    }
                  }
                ]
              }
            }
          ]
        }
      }
    }
  }
}