# Logical OR between query context and filter context with Elasticsearch 2.x

**URL:** <https://discuss.elastic.co/t/logical-or-between-query-context-and-filter-context-with-elasticsearch-2-x/43745>\
**Category:** Elasticsearch\
**Created:** [March 8, 2016, 9:36am UTC](https://discuss.elastic.co/t/logical-or-between-query-context-and-filter-context-with-elasticsearch-2-x/43745 "2016-03-08T09:36:44Z")\
**Posts on this page:** 9\
**Page:** 1

<div class="post-metadata">

**Author:** ![fabioang](https://avatars.discourse-cdn.com/v4/letter/f/848f3c/32.png) [@fabioang](https://discuss.elastic.co/u/fabioang)\
**Post date:** [March 8, 2016, 9:36am UTC](https://discuss.elastic.co/t/logical-or-between-query-context-and-filter-context-with-elasticsearch-2-x/43745/1 "2016-03-08T09:36:45Z")

</div>

Let's say I have an index with the following mapping:

```
PUT my_index
{
  "mappings": {
    "my_type": {
      "properties": {
        "full_text": {
          "type": "string" 
        },
        "exact_value": {
          "type": "string",
          "index": "not_analyzed" 
        }
      }
    }
  }
}
```

and I index a simple document like the following:

```
PUT my_index/my_type/1
{
  "full_text": "This is the city where I live", 
  "exact_value": "MILAN"  
}
```

What I want, it is to create a query that can be logically expressed as:  
`full_text:CONTAINS('live') OR exact_value:CONTAINS('MILAN')`  
But I want to search full\_text in the query context while exact\_value in the filter context  
I tried with the following query but it doesn't work (replacing MILAN with ROME is the prove)

```
POST _search
{
  "query" : {
    "bool" : {
      "filter" : {
        "bool" : {
          "should" : {
            "term" : {
              "exact_value" : "MILAN"
            }
          }
        }
      },
      "should" : {
        "query_string" : {
          "query" : "live",
          "fields" : ["full_text"]
        }
      }
    }
  }
}
```

---

<div class="post-metadata">

**Author:** ![jpountz](https://sea2.discourse-cdn.com/elastic/user_avatar/discuss.elastic.co/jpountz/32/45836_2.png) [@jpountz](https://discuss.elastic.co/u/jpountz)\
**Post date:** [March 8, 2016, 9:52am UTC](https://discuss.elastic.co/t/logical-or-between-query-context-and-filter-context-with-elasticsearch-2-x/43745/2 "2016-03-08T09:52:13Z")

</div>

Having a clause of a disjunction in a filter context makes little sense. What are you trying to achieve?

---

<div class="post-metadata">

**Author:** ![fabioang](https://avatars.discourse-cdn.com/v4/letter/f/848f3c/32.png) [@fabioang](https://discuss.elastic.co/u/fabioang)\
**Post date:** [March 8, 2016, 10:04am UTC](https://discuss.elastic.co/t/logical-or-between-query-context-and-filter-context-with-elasticsearch-2-x/43745/3 "2016-03-08T10:04:20Z")

</div>

I want to achieve a logical OR between two fields but one using the query context and the other one using the filter context. I want to use the filter context to improve performance as suggested in the documentation.

---

<div class="post-metadata">

**Author:** ![jpountz](https://sea2.discourse-cdn.com/elastic/user_avatar/discuss.elastic.co/jpountz/32/45836_2.png) [@jpountz](https://discuss.elastic.co/u/jpountz)\
**Post date:** [March 8, 2016, 10:28am UTC](https://discuss.elastic.co/t/logical-or-between-query-context-and-filter-context-with-elasticsearch-2-x/43745/4 "2016-03-08T10:28:03Z")

</div>

But this works the other way around: you don't decide to put a query in a filter context to make it faster, you need to define a query that meets your needs and then elastisearch will figure out the filter parts and potentially make it faster by doing less work and caching. So if you don't really care about scoring, you could put your exact value query under a `constant_score` query. This way scores won't be needed and your query will execute in a filter context. This will however change the scoring.

---

<div class="post-metadata">

**Author:** ![fabioang](https://avatars.discourse-cdn.com/v4/letter/f/848f3c/32.png) [@fabioang](https://discuss.elastic.co/u/fabioang)\
**Post date:** [March 8, 2016, 11:19am UTC](https://discuss.elastic.co/t/logical-or-between-query-context-and-filter-context-with-elasticsearch-2-x/43745/5 "2016-03-08T11:19:31Z")

</div>

I've just applied the following rules:  
[https://www.elastic.co/guide/en/elasticsearch/guide/current/\_queries\_and\_filters.html](https://www.elastic.co/guide/en/elasticsearch/guide/current/_queries_and_filters.html)

---

<div class="post-metadata">

**Author:** ![fabioang](https://avatars.discourse-cdn.com/v4/letter/f/848f3c/32.png) [@fabioang](https://discuss.elastic.co/u/fabioang)\
**Post date:** [March 8, 2016, 11:59am UTC](https://discuss.elastic.co/t/logical-or-between-query-context-and-filter-context-with-elasticsearch-2-x/43745/6 "2016-03-08T11:59:49Z")

</div>

It looks like it is not possible due to the following restriction:

> **[Bool Query | Elasticsearch Guide \[2.1\] | Elastic](https://www.elastic.co/guide/en/elasticsearch/reference/2.1/query-dsl-bool-query.html)**

> Bool query in filter context  
> If this query is used in a filter context and it has should  
> clauses then at least one should clause is required to match.

---

<div class="post-metadata">

**Author:** ![jpountz](https://sea2.discourse-cdn.com/elastic/user_avatar/discuss.elastic.co/jpountz/32/45836_2.png) [@jpountz](https://discuss.elastic.co/u/jpountz)\
**Post date:** [March 8, 2016, 1:20pm UTC](https://discuss.elastic.co/t/logical-or-between-query-context-and-filter-context-with-elasticsearch-2-x/43745/7 "2016-03-08T13:20:08Z")

</div>

I think the more general issue is that filters are aimed at making the set of potential candidates smaller. While here you want to use a filter in a disjunction, meaning that documents are not required to match the filter in order to match.

---

<div class="post-metadata">

**Author:** ![fabioang](https://avatars.discourse-cdn.com/v4/letter/f/848f3c/32.png) [@fabioang](https://discuss.elastic.co/u/fabioang)\
**Post date:** [March 10, 2016, 3:58pm UTC](https://discuss.elastic.co/t/logical-or-between-query-context-and-filter-context-with-elasticsearch-2-x/43745/8 "2016-03-10T15:58:50Z")

</div>

I found the solution that can be built using the Java API

```
{
      "query" : {
        "bool" : {
          "should" : [ {
            "bool" : {
              "filter" : {
                "term" : {
                  "exact_value" : "MILAN"
                }
              }
            }
          }, {
            "query_string" : {
              "query" : "live",
              "fields" : ["full_text"]
            }
          } ]
        }
      }
    }
```

---

<div class="post-metadata">

**Author:** ![system](https://us1.discourse-cdn.com/elastic/original/3X/1/a/1ac57faf039f6b580b3f104ef42a2a89e41014de.png) [@system](https://discuss.elastic.co/u/system)\
**Post date:** [July 5, 2017, 11:09pm UTC](https://discuss.elastic.co/t/logical-or-between-query-context-and-filter-context-with-elasticsearch-2-x/43745/9 "2017-07-05T23:09:25Z")

</div>


