# Filter if condition is met

**URL:** <https://discuss.elastic.co/t/filter-if-condition-is-met/9071>\
**Category:** Elasticsearch\
**Created:** [September 20, 2012, 5:20am UTC](https://discuss.elastic.co/t/filter-if-condition-is-met/9071 "2012-09-20T05:20:41Z")\
**Posts on this page:** 3\
**Page:** 1

<div class="post-metadata">

**Author:** ![wombat](https://sea2.discourse-cdn.com/elastic/user_avatar/discuss.elastic.co/wombat/32/2713_2.png) [@wombat](https://discuss.elastic.co/u/wombat)\
**Post date:** [September 20, 2012, 5:20am UTC](https://discuss.elastic.co/t/filter-if-condition-is-met/9071/1 "2012-09-20T05:20:41Z")

</div>

Hello fellow ES users,

I've just started looking into elasticsearch, so please point me to an  
existing example if this has already been asked...

What i would like to be able to do is apply a query or filter - but only if  
there is match, otherwise ignore it, a sort of "if" operation.

Here is an example, let's populate the index with two simple docs:

$ curl -XPUT localhost:9200/lucene/fun/1 -d '{  
"field1": "abc",  
"field2": "def",  
"field3": {  
"subfield1": "xyz"  
}  
}'

$ curl -XPUT localhost:9200/lucene/fun/2 -d '{  
"field1": "abc",  
"field2": "def",  
"field3": {  
"subfield1": "tuv"  
}  
}'

If we are certain we have valid, expected input, we can perform a simple  
search:

$ curl -XPOST localhost:9200/lucene/fun/\_search -d '{  
"query": {  
"bool": {  
"must": [  
{  
"term": {  
"field1": "abc"  
}  
},  
{  
"term": {  
"field2": "def"  
}  
}  
]  
}  
}  
}'

That will return the two documents (as expected).

If i want to find just the first document then i can additionally specify  
"field3":  
$ curl -XPOST localhost:9200/lucene/fun/\_search -d '{"query": {"bool":  
{"must": [{"term": {"field1": "abc"}}, {"term": {"field2": "def"}}]}},  
"filter": {"term": {"field3.subfield1": "xyz"}}}'

And that returns just the first document (again as expected).

The question is what query can i construct if i am given a potential value  
for "field3.subfield1" but i don't know if its a valid value for the field.  
So if it is found, then only return documents with that value for the  
specified field, but if it isn't, then return all documents and ignore the  
specified field.

Attempting to use "should" doesn't filter the results - for example the  
following query returns both documents:  
$ curl -XPOST localhost:9200/lucene/fun/\_search -d '{"query": {"bool":  
{"must": [{"term": {"field1": "abc"}}, {"term": {"field2": "def"}}],  
"should": [{"term": {"field3.subfield1": "xyz"}}]}}}'

Thanks for any help.

--

---

<div class="post-metadata">

**Author:** ![Clinton\_Gormley](https://avatars.discourse-cdn.com/v4/letter/c/50afbb/32.png) [@Clinton\_Gormley](https://discuss.elastic.co/u/Clinton_Gormley)\
**Post date:** [September 20, 2012, 8:42am UTC](https://discuss.elastic.co/t/filter-if-condition-is-met/9071/2 "2012-09-20T08:42:37Z")

</div>

Hiya

> The question is what query can i construct if i am given a potential  
> value for "field3.subfield1" but i don't know if its a valid value for  
> the field. So if it is found, then only return documents with that  
> value for the specified field, but if it isn't, then return all  
> documents and ignore the specified field.

You can't. A query is essentially a filter which is applied to each  
individual document. It doesn't know about the other results.

So you either need to do two queries, or a single query which will  
include the "field3" doc first, if it exists.

However, you can used NAMED filters to identify matching docs more  
easily. For instance:

curl -XGET '[http://127.0.0.1:9200/iannounce\_object/\_search?pretty=1](http://127.0.0.1:9200/iannounce_object/_search?pretty=1)' -d  
'  
{  
"query" : {  
"custom\_filters\_score" : {  
"query" : {  
"text" : { "\_all": "foobar"}  
},  
"filters" : [  
{  
"boost" : "10",  
"filter" : {  
"term" : {  
"\_name" : "xyz",  
"field3.subfield1" : "xyz"  
}  
}  
}  
]  
}  
}  
}  
'

If there is a doc that has field3.subfield1 == 'xyz' then that doc will  
appear first in the list, and matching results will include:

```
matched_filters: ["xyz"]

```

clint

--

---

<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 6, 2017, 3:12am UTC](https://discuss.elastic.co/t/filter-if-condition-is-met/9071/3 "2017-07-06T03:12:10Z")

</div>


