# Several should inside a must?

**URL:** <https://discuss.elastic.co/t/several-should-inside-a-must/130620>\
**Category:** Elasticsearch\
**Created:** [May 4, 2018, 11:58am UTC](https://discuss.elastic.co/t/several-should-inside-a-must/130620 "2018-05-04T11:58:36Z")\
**Posts on this page:** 5\
**Page:** 1

<div class="post-metadata">

**Author:** ![GaldanM](https://sea2.discourse-cdn.com/elastic/user_avatar/discuss.elastic.co/galdanm/32/29866_2.png) [@GaldanM](https://discuss.elastic.co/u/GaldanM)\
**Post date:** [May 4, 2018, 11:58am UTC](https://discuss.elastic.co/t/several-should-inside-a-must/130620/1 "2018-05-04T11:58:36Z")

</div>

Hello there, I'm pretty new to the ES stack and I'm actually replacing a Mongo text query by ES.

I need some help to build a query : I need to search in text indexed fields of an index BUT I also want to be able to filter the results by 3 fields (which are actually ids so no chance of conflict with other fields). I'll try to explain what problem I'm facing :

Let's say that those fields are carts where I can put items, so the carts will be array of strings. I want to be able to filter the results by docs who have some items in one of the carts. For example, I want the docs that only have carts that possess 'Salt' AND 'Sugar', but 'Salt' can be in \_cart1 and 'Sugar' in \_cart3.

I already have a query that's close, the only notion I'm missing is : is it possible to have a filter that will have a MUST which contains several SHOULD ?

This is the query that I have for now :

```
query: {
    bool: {
	must: {
	    query_string: {
	        fields: [
		    'aField^5',
		    'anotherOne^10',
	            'lastField',
		],
		query: '*',
	    },
	},
	filter: [
		  {
		    bool: {
			should: [
			  {
			    terms: {
			        _cart1: [
				  'Sugar',
			          'Salt',
				],
			     },
			  },
                          {
			    terms: {
			        _cart2: [
				  'Sugar',
			          'Salt',
				],
			    },
			  },
                          {
			    terms: {
			        _cart3: [
				  'Sugar',
			          'Salt',
				],
			    },
			  },
		       ],
		     },
		   },
		],
	},
},
```

---

<div class="post-metadata">

**Author:** ![ddorian43](https://sea2.discourse-cdn.com/elastic/user_avatar/discuss.elastic.co/ddorian43/32/36093_2.png) [@ddorian43](https://discuss.elastic.co/u/ddorian43)\
**Post date:** [May 4, 2018, 12:57pm UTC](https://discuss.elastic.co/t/several-should-inside-a-must/130620/2 "2018-05-04T12:57:58Z")

</div>

You can do a combination of:  
`should:[must{cart_1: sugar, cart_2:salt}, must{cart_2:sugar, cart_1:salt}, must{cart_1:sugar, cart_1:salt}, must{cart_2:sugar, cart_2:salt}]`. Each of those is a `term` filter.

Makes sense ? I did for 2 fields but can be expanded into `n` fields.

---

<div class="post-metadata">

**Author:** ![ddorian43](https://sea2.discourse-cdn.com/elastic/user_avatar/discuss.elastic.co/ddorian43/32/36093_2.png) [@ddorian43](https://discuss.elastic.co/u/ddorian43)\
**Post date:** [May 4, 2018, 1:05pm UTC](https://discuss.elastic.co/t/several-should-inside-a-must/130620/3 "2018-05-04T13:05:05Z")

</div>

If you have multiple `cart_n` fields, and you are searching for multiple keywords, say `10+`, you can create a `cart_all: array(string)` that has all values from all carts and only search into that one. This will result into bigger data (since you're duplicating) but faster search (since you're intersecting fewer filters).

And the point when it's better to use either way will depend on your requirements for search-latency / data-size.

---

<div class="post-metadata">

**Author:** ![GaldanM](https://sea2.discourse-cdn.com/elastic/user_avatar/discuss.elastic.co/galdanm/32/29866_2.png) [@GaldanM](https://discuss.elastic.co/u/GaldanM)\
**Post date:** [May 4, 2018, 1:10pm UTC](https://discuss.elastic.co/t/several-should-inside-a-must/130620/4 "2018-05-04T13:10:15Z")

</div>

You first answer makes sense to me, I just didn't know you could put a must directly after a should.

Second answer would make a lot more sense but I will need to have those 3 distinct carts in the future because I want to be able to filter only on the first one or something like that.

I will try your solution and see if it works ! Thanks 🙂

---

<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:** [June 1, 2018, 1:10pm UTC](https://discuss.elastic.co/t/several-should-inside-a-must/130620/5 "2018-06-01T13:10:16Z")

</div>

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