Several should inside a must?


(Galdan Moulinneuf) #1

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',
				],
			    },
			  },
		       ],
		     },
		   },
		],
	},
},

(ddorian43) #2

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.


(ddorian43) #3

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.


(Galdan Moulinneuf) #4

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 :slight_smile:


(system) #5

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