# Need multiple post\_filter condition

**URL:** https://discuss.elastic.co/t/need-multiple-post-filter-condition/156255
**Category:** Elasticsearch
**Created:** [November 12, 2018, 8:47am UTC](https://discuss.elastic.co/t/need-multiple-post-filter-condition/156255 "2018-11-12T08:47:56Z")
**Posts on this page:** 18
**Page:** 1

<div class="post-metadata">

### Author: ![fardhana](https://sea2.discourse-cdn.com/elastic/user_avatar/discuss.elastic.co/fardhana/32/37533_2.png) [@fardhana](https://discuss.elastic.co/u/fardhana)
#### Post date: [November 12, 2018, 8:47am UTC](https://discuss.elastic.co/t/need-multiple-post-filter-condition/156255/1 "2018-11-12T08:47:56Z")

</div>

Hi,

I have directory listing site that use elasticsearch as search engine. In this site people able to:

1. Find the most related doc by keyword (keyword will be checked to multiple field)
2. sort by nearest location and limit between radius 20km

My approach is by using this json doc:  
`{ "query": { "bool": { "should": [{ "match": { "organic_keywords": { "query": "resto padang", "operator": "and", "boost": 0.3 } } }, { "match": { "keywords": { "query": "resto padang", "operator": "and", "boost": 0.4 } } }, { "match": { "category.id": { "query": "resto padang", "operator": "and", "boost": 0.7 } } }, { "match": { "category.en": { "query": "resto padang", "operator": "and", "boost": 0.7 } } }, { "match": { "name": { "query": "resto padang", "operator": "and", "boost": 1 } } }, { "match": { "popular_name": { "query": "resto padang", "operator": "and", "boost": 1.2 } } }, { "match": { "products.name": { "query": "resto padang", "operator": "and", "boost": 1.3 } } }] } }, "sort": [{ "_geo_distance": { "coordinates": { "lat": "-6.244668099999999", "lon": "106.84092849999999" }, "order": "asc", "unit": "km" } }], "post_filter": { "geo_distance": { "distance": "20km", "coordinates": { "lat": "-6.244668099999999", "lon": "106.84092849999999" } } }, "from": 0, "size": 10 }`

Now, i have more filter. **Only search to document with field published=1**.  
And the filter that i plan to used to accomplished that is by using `post_filter`, unfortunately as far as i know, `post_filter` is not accept array object.

What is the solution for this situation?

Thanks

---

<div class="post-metadata">

### Author: ![mvg](https://sea2.discourse-cdn.com/elastic/user_avatar/discuss.elastic.co/mvg/32/98890_2.png) [@mvg](https://discuss.elastic.co/u/mvg)
#### Post date: [November 12, 2018, 10:08am UTC](https://discuss.elastic.co/t/need-multiple-post-filter-condition/156255/2 "2018-11-12T10:08:31Z")

</div>

You can just add a bool query inside `post_filter` and inside the bool query add your `geo_distance` and a `term` (for `published=1`) as filter clause.

I do wonder why you use post\_filter. It only makes sense in combination with aggregations, in order to show counts where certain filter are not applied. If you don't need to do that, then I recommend you to place your filters in the `filter` clause of the `bool` query that you already have defined as your main query. This way the query will execute much more efficiently.

---

<div class="post-metadata">

### Author: ![fardhana](https://sea2.discourse-cdn.com/elastic/user_avatar/discuss.elastic.co/fardhana/32/37533_2.png) [@fardhana](https://discuss.elastic.co/u/fardhana)
#### Post date: [November 12, 2018, 12:21pm UTC](https://discuss.elastic.co/t/need-multiple-post-filter-condition/156255/3 "2018-11-12T12:21:56Z")

</div>

Hi! Thanks for the reply. I will try it, and grt back with the result.

I use post\_filter here to get document matched with keyword, which still in 20km in radius.

I'have try it (use query filter instead post\_filter). If i put the geo filter on query filter clause, then i will get "not matched" with keyword document in less relevant result, right? Which we just want to result only matched keyword document.

CMIIW, anyway let me know if there is better approach for my search criteria.

Thanks

---

<div class="post-metadata">

### Author: ![mvg](https://sea2.discourse-cdn.com/elastic/user_avatar/discuss.elastic.co/mvg/32/98890_2.png) [@mvg](https://discuss.elastic.co/u/mvg)
#### Post date: [November 12, 2018, 1:32pm UTC](https://discuss.elastic.co/t/need-multiple-post-filter-condition/156255/4 "2018-11-12T13:32:24Z")

</div>

> [@fardhana](#):
>
> I'have try it (use query filter instead post\_filter). If i put the geo filter on query filter clause, then i will get "not matched" with keyword document in less relevant result, right?

Queries inside `bool` query's `filter` clause don't contribute to the score, so they don't make a document more relevant. A filter clause either does or doesn't match and a document need to match with all filter clauses otherwise it is not a hit. That behaviour is similar to what you have experienced when placing a query inside the `post_filter`.

---

<div class="post-metadata">

### Author: ![fardhana](https://sea2.discourse-cdn.com/elastic/user_avatar/discuss.elastic.co/fardhana/32/37533_2.png) [@fardhana](https://discuss.elastic.co/u/fardhana)
#### Post date: [November 12, 2018, 2:01pm UTC](https://discuss.elastic.co/t/need-multiple-post-filter-condition/156255/5 "2018-11-12T14:01:56Z")

</div>

So in my case, both filter radius and published=1 better be placed in filter clause?

If not yet tested, still on mobile.

---

<div class="post-metadata">

### Author: ![mvg](https://sea2.discourse-cdn.com/elastic/user_avatar/discuss.elastic.co/mvg/32/98890_2.png) [@mvg](https://discuss.elastic.co/u/mvg)
#### Post date: [November 12, 2018, 2:28pm UTC](https://discuss.elastic.co/t/need-multiple-post-filter-condition/156255/6 "2018-11-12T14:28:24Z")

</div>

Yes, I think that would be better.

---

<div class="post-metadata">

### Author: ![fardhana](https://sea2.discourse-cdn.com/elastic/user_avatar/discuss.elastic.co/fardhana/32/37533_2.png) [@fardhana](https://discuss.elastic.co/u/fardhana)
#### Post date: [November 13, 2018, 2:32am UTC](https://discuss.elastic.co/t/need-multiple-post-filter-condition/156255/7 "2018-11-13T02:32:49Z")

</div>

Hi, I've try the bool query inside `post_filter` it's work. thanks!

But, the interesting thing is regarding moving `post_filter` query to `bool`query.  
as i said, the result is not as expected.

The document which not contained the keyword is appear.  
Do i need to create separate topic for this?

Thanks

---

<div class="post-metadata">

### Author: ![mvg](https://sea2.discourse-cdn.com/elastic/user_avatar/discuss.elastic.co/mvg/32/98890_2.png) [@mvg](https://discuss.elastic.co/u/mvg)
#### Post date: [November 13, 2018, 9:11am UTC](https://discuss.elastic.co/t/need-multiple-post-filter-condition/156255/8 "2018-11-13T09:11:21Z")

</div>

> [@fardhana](#):
>
> The document which not contained the keyword is appear.  
> Do i need to create separate topic for this?

Can you share the query that you're executing?

---

<div class="post-metadata">

### Author: ![fardhana](https://sea2.discourse-cdn.com/elastic/user_avatar/discuss.elastic.co/fardhana/32/37533_2.png) [@fardhana](https://discuss.elastic.co/u/fardhana)
#### Post date: [November 13, 2018, 9:52am UTC](https://discuss.elastic.co/t/need-multiple-post-filter-condition/156255/9 "2018-11-13T09:52:36Z")

</div>

Here my query.

`{ "query": { "bool": { "filter": [{ "term": { "published": 1 } }, { "geo_distance": { "distance": "20km", "coordinates": { "lat": "-6.2446641", "lon": "106.8409247" } } }], "should": [{ "match": { "organic_keywords": { "query": "hotel murah", "operator": "and", "boost": 0.3 } } }, { "match": { "keywords": { "query": "hotel murah", "operator": "and", "boost": 0.4 } } }, { "match": { "category.id": { "query": "hotel murah", "operator": "and", "boost": 0.7 } } }, { "match": { "category.en": { "query": "hotel murah", "operator": "and", "boost": 0.7 } } }, { "match": { "name": { "query": "hotel murah", "operator": "and", "boost": 1 } } }, { "match": { "popular_name": { "query": "hotel murah", "operator": "and", "boost": 1.2 } } }, { "match": { "products.name": { "query": "hotel murah", "operator": "and", "boost": 1.3 } } }] } }, "sort": [{ "_geo_distance": { "coordinates": { "lat": "-6.2446641", "lon": "106.8409247" }, "order": "asc", "unit": "km" } }], "from": 0, "size": 10 }`

When i use this query total document hit is `98034`  
but when i use `post_filter` the document hit is `93`

Thanks

---

<div class="post-metadata">

### Author: ![mvg](https://sea2.discourse-cdn.com/elastic/user_avatar/discuss.elastic.co/mvg/32/98890_2.png) [@mvg](https://discuss.elastic.co/u/mvg)
#### Post date: [November 13, 2018, 11:13am UTC](https://discuss.elastic.co/t/need-multiple-post-filter-condition/156255/10 "2018-11-13T11:13:55Z")

</div>

and can you also share the query with `post_filter`?

---

<div class="post-metadata">

### Author: ![fardhana](https://sea2.discourse-cdn.com/elastic/user_avatar/discuss.elastic.co/fardhana/32/37533_2.png) [@fardhana](https://discuss.elastic.co/u/fardhana)
#### Post date: [November 14, 2018, 2:05am UTC](https://discuss.elastic.co/t/need-multiple-post-filter-condition/156255/11 "2018-11-14T02:05:25Z")

</div>

By using query below, document hit is `93`  
Please check, thanks

`{ "query": { "bool": { "should": [{ "match": { "organic_keywords": { "query": "hotel murah", "operator": "and", "boost": 0.3 } } }, { "match": { "keywords": { "query": "hotel murah", "operator": "and", "boost": 0.4 } } }, { "match": { "category.id": { "query": "hotel murah", "operator": "and", "boost": 0.7 } } }, { "match": { "category.en": { "query": "hotel murah", "operator": "and", "boost": 0.7 } } }, { "match": { "name": { "query": "hotel murah", "operator": "and", "boost": 1 } } }, { "match": { "popular_name": { "query": "hotel murah", "operator": "and", "boost": 1.2 } } }, { "match": { "products.name": { "query": "hotel murah", "operator": "and", "boost": 1.3 } } }] } }, "post_filter": { "bool": { "filter": [{ "term": { "published": 1 } }, { "geo_distance": { "distance": "20km", "coordinates": { "lat": "-6.2446641", "lon": "106.8409247" } } }] } }, "sort": [{ "_geo_distance": { "coordinates": { "lat": "-6.2446641", "lon": "106.8409247" }, "order": "asc", "unit": "km" } }], "from": 0, "size": 10 }`

---

<div class="post-metadata">

### Author: ![mvg](https://sea2.discourse-cdn.com/elastic/user_avatar/discuss.elastic.co/mvg/32/98890_2.png) [@mvg](https://discuss.elastic.co/u/mvg)
#### Post date: [November 14, 2018, 8:09am UTC](https://discuss.elastic.co/t/need-multiple-post-filter-condition/156255/12 "2018-11-14T08:09:02Z")

</div>

Thanks for sharing that. The difference in hit count is unexpected to me. I think somehow the `term` query (for published=1) gets parsed differently in the two search requests.

1. Can you execute both queries in the validate query API (`/_validate/query?explain=true&rewrite=true`)?

2. Also I like to know whether the results are still the same if the `match` query is used instead of the `term` query for `published=1`.

---

<div class="post-metadata">

### Author: ![fardhana](https://sea2.discourse-cdn.com/elastic/user_avatar/discuss.elastic.co/fardhana/32/37533_2.png) [@fardhana](https://discuss.elastic.co/u/fardhana)
#### Post date: [November 14, 2018, 10:55am UTC](https://discuss.elastic.co/t/need-multiple-post-filter-condition/156255/13 "2018-11-14T10:55:59Z")

</div>

Hi Martijn, thanks a lot for your help.

> [@mvg](#):
>
> Can you execute both queries in the validate query API ( `/_validate/query?explain=true&rewrite=true` )?

`_validate` endpoint doesn't support `post_filter`, `sort`, `from` and `size` it's give a and error. that's why i cannot share the output with `post_filter` query.

Here the outpur for `filter` clause:  
`{ "_shards": { "total": 1, "successful": 1, "failed": 0 }, "valid": true, "explanations": [{ "index": "yellowpages", "valid": true, "explanation": "(+organic_keywords:hotel +organic_keywords:murah)^0.3 (+keywords:hotel +keywords:murah)^0.4 (+category.id:hotel +category.id:murah)^0.7 (+category.en:hotel +category.en:murah)^0.7 (+name:hotel +name:murah) (+popular_name:hotel +popular_name:murah)^1.2 (+products.name:hotel +products.name:murah)^1.3 #published:[1 TO 1] #coordinates:-6.2446641,106.8409247 +/- 20000.0 meters" } ] }`

> [@mvg](#):
>
> Also I like to know whether the results are still the same if the `match` query is used instead of the `term` query for `published=1` .

Same result when trying with `match` query. Do you have another clue? 🙂

---

<div class="post-metadata">

### Author: ![mvg](https://sea2.discourse-cdn.com/elastic/user_avatar/discuss.elastic.co/mvg/32/98890_2.png) [@mvg](https://discuss.elastic.co/u/mvg)
#### Post date: [November 14, 2018, 12:50pm UTC](https://discuss.elastic.co/t/need-multiple-post-filter-condition/156255/14 "2018-11-14T12:50:28Z")

</div>

> [@fardhana](#):
>
> `_validate` endpoint doesn't support `post_filter` , `sort` , `from` and `size` it's give a and error. that's why i cannot share the output with `post_filter` query.

Ah sorry for recommending that. It only support queries inside a top level `query` json object.

Can you set `minimum_should_match` set `1` on the query using bool `query` with filter clauses?

---

<div class="post-metadata">

### Author: ![fardhana](https://sea2.discourse-cdn.com/elastic/user_avatar/discuss.elastic.co/fardhana/32/37533_2.png) [@fardhana](https://discuss.elastic.co/u/fardhana)
#### Post date: [November 14, 2018, 1:38pm UTC](https://discuss.elastic.co/t/need-multiple-post-filter-condition/156255/15 "2018-11-14T13:38:25Z")

</div>

> [@mvg](#):
>
> Can you set `minimum_should_match` set `1` on the query using bool `query` with filter clauses?

Cool!! the hit count now same when i use `post_filter`, thanks Martijn.  
What's magic behind that clause?

And what is advantages when i using query instead `post_filter`? Does query performance increased?

Thanks!

---

<div class="post-metadata">

### Author: ![mvg](https://sea2.discourse-cdn.com/elastic/user_avatar/discuss.elastic.co/mvg/32/98890_2.png) [@mvg](https://discuss.elastic.co/u/mvg)
#### Post date: [November 14, 2018, 2:07pm UTC](https://discuss.elastic.co/t/need-multiple-post-filter-condition/156255/16 "2018-11-14T14:07:48Z")

</div>

> [@fardhana](#):
>
> What's magic behind that clause?

A `bool` query with only should clauses automatically sets `minimum_should_match` to `1` if it has not been specified. A `bool` query with should clauses and required clauses (filter or must), the `minimum_should_match` is set to `0` if it has not been specified. The idea behind this is that if there are only should clauses, at one should clause must match (otherwise all documents would match). If there are required clauses then should clauses are optional by default. I had forgotten this detail 🙂

> [@fardhana](#):
>
> And what is advantages when i using query instead `post_filter` ? Does query performance increased?

Yes, Elasticsearch is then able in many cases to execute the search request more efficiently, so if you can place queries in the `bool` query's filter clause then you should do that.

---

<div class="post-metadata">

### Author: ![fardhana](https://sea2.discourse-cdn.com/elastic/user_avatar/discuss.elastic.co/fardhana/32/37533_2.png) [@fardhana](https://discuss.elastic.co/u/fardhana)
#### Post date: [November 15, 2018, 6:49am UTC](https://discuss.elastic.co/t/need-multiple-post-filter-condition/156255/17 "2018-11-15T06:49:22Z")

</div>

Thanks @mvg for your time and help.

Thank you!

---

<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: [December 13, 2018, 6:49am UTC](https://discuss.elastic.co/t/need-multiple-post-filter-condition/156255/18 "2018-12-13T06:49:30Z")

</div>

This topic was automatically closed 28 days after the last reply. New replies are no longer allowed.
