# Filter Query result by collection

**URL:** https://discuss.elastic.co/t/filter-query-result-by-collection/62033
**Category:** Elasticsearch
**Created:** [October 3, 2016, 7:59am UTC](https://discuss.elastic.co/t/filter-query-result-by-collection/62033 "2016-10-03T07:59:12Z")
**Posts on this page:** 6
**Page:** 1

<div class="post-metadata">

### Author: ![Andrey\_Kaprov](https://sea2.discourse-cdn.com/elastic/user_avatar/discuss.elastic.co/andrey_kaprov/32/12262_2.png) [@Andrey\_Kaprov](https://discuss.elastic.co/u/Andrey_Kaprov)
#### Post date: [October 3, 2016, 7:59am UTC](https://discuss.elastic.co/t/filter-query-result-by-collection/62033/1 "2016-10-03T07:59:12Z")

</div>

Good day, everyone! I have an indexed object Topic with mapping:  
"topic": {  
"properties": {  
"authorName": {  
"type": "string"  
},  
"categoryId": {  
"type": "string"  
},  
"description": {  
"type": "string"  
}  
}  
}

I use NEST 2.0 to search between my indexed Topics with the C# query:

var searchEngineResult = await  
ElasticClient.SearchAsync(  
r =\> r.AllIndices()  
.Source(false)  
.Query(q =\> q.Match(m =\> m.Field(AllFieldsToken).Operator(Operator.And).Query(query)))  
);

It works perfectly, but I need to filter search results on the categoryId collection.  
For example:

there is 3 indexed topics:

1. authorName = "Some guy", categoryId = "cat2", description = "some toric";
2. authorName = "Second guy", categoryId = "cat1", description = "some other topic";
3. authorName = "Third dude", categoryId = "cat2", description = "third topic";
4. authorName = "Fourth guy", categoryId = "cat1", description = "topic topic";

String[] categoryId = new[] {"cat1, "cat2" };

If I will search for "guy topic" I can obtain topics 1, 2 and 4.  
And now I need to filter my search result with the categoryId.  
There can be multiple comma separated categoryIds for filtering.  
i.e.  
if I will filter with "cat2" I expect topic 1.  
if I will filter with "cat1" I expect topics 2 and 4.  
if I will filter with "cat1,cat2" I expect topics 1, 2 and 4

In the mean time I need to filter all of the topics without query

How can I implement this?

---

<div class="post-metadata">

### Author: ![Andrey\_Kaprov](https://sea2.discourse-cdn.com/elastic/user_avatar/discuss.elastic.co/andrey_kaprov/32/12262_2.png) [@Andrey\_Kaprov](https://discuss.elastic.co/u/Andrey_Kaprov)
#### Post date: [October 3, 2016, 9:17am UTC](https://discuss.elastic.co/t/filter-query-result-by-collection/62033/2 "2016-10-03T09:17:29Z")

</div>

In other words: How can I implement this with NEST:  
{  
"query": {  
"constant\_score" : {  
"filter" : {  
"bool": {  
"must" : {  
"term" : {  
"\_all" : "guy topic"  
}  
},  
"should" : [  
{  
"term" : {  
"categoryId" : "cat1"  
}  
},  
{  
"term" : {  
"categoryId" : "cat2"  
}  
}  
]  
}  
}  
}  
}  
}

---

<div class="post-metadata">

### Author: ![Martijn\_Laarman](https://sea2.discourse-cdn.com/elastic/user_avatar/discuss.elastic.co/martijn_laarman/32/4410_2.png) [@Martijn\_Laarman](https://discuss.elastic.co/u/Martijn_Laarman)
#### Post date: [October 3, 2016, 9:28am UTC](https://discuss.elastic.co/t/filter-query-result-by-collection/62033/3 "2016-10-03T09:28:02Z")

</div>

When a bool clause with a must has should clauses the `minimum_should_match` defaults to 0 meaning that that query will return all documents matching `guy topic` and if they happen to contain `catagoryId: "cat1"` or `catagoryId: "cat2"` these documents will score better then other documents containing `guy topic`. Other documents with different catagories will **still be returned**. This is due to the unary nature of boolean queries in Elasticsearch.

The query you posted translates to `+"guy topic" catagoryId:cat1 catagoryId:cat2` not `"guy topic" AND (catagoryId:cat1 OR catagoryId:cat2)`

In NEST you can use bitwise operators to construct true boolean queries.

```auto
q=>q.Term("_all", "guy topic") 
   && (q.Term("catagoryId", "cat1") || q.Term("catagoryId", "cat1"))

```

Which will translate to a bool query with 2 must clauses, one being the \_all term query and the other being a nested bool with _only_ should clauses (the two term queries). When a boolean query has only should clauses the `minimum_should_match` defaults to 1.

Also do checkout [the terms query](https://www.elastic.co/guide/en/elasticsearch/reference/current/query-dsl-terms-query.html)

---

<div class="post-metadata">

### Author: ![Andrey\_Kaprov](https://sea2.discourse-cdn.com/elastic/user_avatar/discuss.elastic.co/andrey_kaprov/32/12262_2.png) [@Andrey\_Kaprov](https://discuss.elastic.co/u/Andrey_Kaprov)
#### Post date: [October 3, 2016, 9:53am UTC](https://discuss.elastic.co/t/filter-query-result-by-collection/62033/4 "2016-10-03T09:53:34Z")

</div>

Thanks for the reply! Your suggestion is works as expected, thank you! But I need to implement this search request with unknown categoryId count. I mean I need to FOREACH them somehow and add them to the query

---

<div class="post-metadata">

### Author: ![Andrey\_Kaprov](https://sea2.discourse-cdn.com/elastic/user_avatar/discuss.elastic.co/andrey_kaprov/32/12262_2.png) [@Andrey\_Kaprov](https://discuss.elastic.co/u/Andrey_Kaprov)
#### Post date: [October 3, 2016, 10:10am UTC](https://discuss.elastic.co/t/filter-query-result-by-collection/62033/5 "2016-10-03T10:10:45Z")

</div>

Tjis is how I worked it out:

```
var boolQuery = new BoolQuery();
        boolQuery.Must = new[] { new QueryContainerDescriptor<Object>().Match(m => m.Field(AllFieldsToken).Operator(Operator.And).Query(query)) };

        if (searchRequest.CategoryIds.Count() > 0)
        {
            List<QueryContainer> shouldContainer = new List<QueryContainer>();

            foreach (var catId in searchRequest.CategoryIds)
            {
                shouldContainer.Add(new QueryContainerDescriptor<Object>().Match(m => m.Field("categoryId").Query(catId)));
            }

            boolQuery.Should = shouldContainer.ToArray();
        }
        boolQuery.MinimumShouldMatch = new MinimumShouldMatch(1);

```

and then the query:

```
var searchResult = ElasticClient.....Query(q => boolQuery)
```

---

<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, 10:15pm UTC](https://discuss.elastic.co/t/filter-query-result-by-collection/62033/6 "2017-07-05T22:15:29Z")

</div>


