Rescoring and Sorting of documents - sorting

My goal is to write a query which would rescore documents based on value of a field in the document. To achieve this I was using a rescore query and then sorting the results. However, an explain on the query shows me that the sorting of the documents is done based on the previously computed score and not the new one.
I saw the following which explains that I couldn't use rescore and sort together.
"Sometimes we want to show results, where the ordering of the first documents on the page is affected by the additional rules. Unfortunately this cannot be achieved by the rescore functionality. The first idea points to window_size parameter, but this parameter in fact is not connected with the first documents on the result list but with number of results returned on every shard. In addition window_size cannot be less than page size. (If it is less, ElasticSearch silently use page size). Also, one very important thing – rescoring cannot be combined with sorting, because sorting is done after changes introduced by rescoring."
http://elasticsearchserverbook.com/elasticsearch-0-90-using-rescore/
My query is:
{
"query": {
"filtered": {
"query": {
"bool": {
"should": [
{
"constant_score": {
"query": {
"match": {
"question": {
"query": "diabetes"
}
}
},
"boost": 1
}
},
{
"dis_max": {
"queries": [
{
"constant_score": {
"query": {
"match": {
"question": {
"query": "diabetes"
}
}
},
"boost": 0.01
}
},
{
"constant_score": {
"query": {
"match": {
"answer_text": {
"query": "diabetes"
}
}
},
"boost": 0.0001
}
}
]
}
},
{
"dis_max": {
"queries": [
{
"constant_score": {
"query": {
"match_phrase": {
"question_phrase": {
"query": "what is diabetes",
"slop": 0
}
}
},
"boost": 100
}
},
{
"constant_score": {
"query": {
"match_phrase": {
"question_phrase": {
"query": "what is diabetes",
"slop": 1
}
}
},
"boost": 50
}
},
{
"constant_score": {
"query": {
"match_phrase": {
"question_phrase": {
"query": "what is diabetes",
"slop": 2
}
}
},
"boost": 33
}
},
{
"constant_score": {
"query": {
"match_phrase": {
"question_phrase": {
"query": "what is diabetes",
"slop": 3
}
}
},
"boost": 25
}
},
{
"constant_score": {
"query": {
"query_string": {
"default_field": "question_group_four",
"query": "what__is__diabetes"
}
},
"boost": 0.1
}
},
{
"constant_score": {
"query": {
"query_string": {
"default_field": "question_group_five",
"query": "what__is__diabetes"
}
},
"boost": 0.15
}
},
{
"constant_score": {
"query": {
"query_string": {
"default_field": "concept_words_no_synonyms_20",
"query": "what__is__diabetes"
}
},
"boost": 35
}
},
{
"constant_score": {
"query": {
"query_string": {
"default_field": "concept_words_no_synonyms_15",
"query": "what__is__diabetes"
}
},
"boost": 25
}
},
{
"constant_score": {
"query": {
"query_string": {
"default_field": "concept_words_no_synonyms_10",
"query": "what__is__diabetes"
}
},
"boost": 15
}
},
{
"constant_score": {
"query": {
"query_string": {
"default_field": "concept_words_20",
"query": "what__is__diabetes"
}
},
"boost": 28
}
},
{
"constant_score": {
"query": {
"query_string": {
"default_field": "concept_words_15",
"query": "what__is__diabetes"
}
},
"boost": 16
}
},
{
"constant_score": {
"query": {
"query_string": {
"default_field": "concept_words_10",
"query": "what__is__diabetes"
}
},
"boost": 13
}
},
{
"constant_score": {
"query": {
"query_string": {
"default_field": "concept_words_05",
"query": "what__is__diabetes"
}
},
"boost": 4
}
}
]
}
},
{
"dis_max": {
"queries": [
{
"constant_score": {
"query": {
"query_string": {
"default_field": "question_group_four",
"query": "diabetes"
}
},
"boost": 0.1
}
},
{
"constant_score": {
"query": {
"query_string": {
"default_field": "question_group_five",
"query": "diabetes"
}
},
"boost": 0.15
}
},
{
"constant_score": {
"query": {
"query_string": {
"default_field": "concept_words_no_synonyms_20",
"query": "diabetes"
}
},
"boost": 35
}
},
{
"constant_score": {
"query": {
"query_string": {
"default_field": "concept_words_no_synonyms_15",
"query": "diabetes"
}
},
"boost": 25
}
},
{
"constant_score": {
"query": {
"query_string": {
"default_field": "concept_words_no_synonyms_10",
"query": "diabetes"
}
},
"boost": 15
}
},
{
"constant_score": {
"query": {
"query_string": {
"default_field": "concept_words_20",
"query": "diabetes"
}
},
"boost": 28
}
},
{
"constant_score": {
"query": {
"query_string": {
"default_field": "concept_words_15",
"query": "diabetes"
}
},
"boost": 16
}
},
{
"constant_score": {
"query": {
"query_string": {
"default_field": "concept_words_10",
"query": "diabetes"
}
},
"boost": 13
}
},
{
"constant_score": {
"query": {
"query_string": {
"default_field": "concept_words_05",
"query": "diabetes"
}
},
"boost": 4
}
}
]
}
}
],
"disable_coord": true
}
},
"filter": {
"and": [
{
"term": {
"posted_by_expert": false
}
},
{
"term": {
"tip_question": false
}
},
{
"term": {
"show_in_work_queue": true
}
},
{
"range": {
"verified_answers_count": {
"gt": 0
}
}
}
]
}
}
},
"rescore": {
"window_size": 100,
"query": {
"rescore_query": {
"function_score": {
"functions": [
{
"script_score": {
"script": "_score * _source.concierge_boost"
}
}
]
}
}
}
},
"sort": [
"_score",
{
"count_words_with_high_concepts": {
"order": "asc"
}
},
{
"popularity": {
"order": "desc"
}
},
{
"length": {
"order": "asc"
}
}
],
"fields": [],
"size": 10,
"from": 0
}
Any help highly appreciated !

This is not possible, indeed. But this has been discussed and decided is not worth implementing it at the moment. The discussion on github, though, reveals the difficulty about this - documents need to be sorted, top 100 (in your case) chosen, then a rescore is applied and then they are, again, sorted. I suggest reading the comments in that github issue, especially the ones from simonw. The issue is still open but it doesn't seem it will be implemented soon, if it will at all.
Regarding your sorting after another level of scoring, I understand the need to rescore only few documents, but it seems is not possible. What if you wrap your query in another function_score where you define a script_score function to compute the final score? Something like this:
{
"query": {
"function_score": {
"query": {
.......
},
"functions": [
{
"script_score": {
"script": "doc['concierge_boost'].value"
}
}
]
}
},
"sort": [
"_score",
{
"count_words_with_high_concepts": {
"order": "asc"
}
},
{
"popularity": {
"order": "desc"
}
},
{
"length": {
"order": "asc"
}
}
],
"fields": [],
"size": 10,
"from": 0
}

Related

Minimum should match with filter doesn't return any result

I have a complicated query which works fine.the proble is that I'm going to add a condition(filter) to it to filter the result.I need the exact result that I currently get with filtering based on the field called "field7".
"query": {
"bool": {
"should": [
{
"match_bool_prefix": {
"field1": {
"query": "test",
"fuzziness": "auto",
"boost": 1
}
}
},
{
"match": {
"field2": {
"query": "test",
"boost": 10
}
}
},
{
"exists": {
"field": "field3",
"boost": 15
}
},
{
"exists": {
"field": "field4",
"boost": 10
}
},
{
"match_phrase_prefix": {
"field5": {
"query": ""
}
}
}
],
"must": [
{
"bool": {
"filter": [
{
"match": {
"field6": "A"
}
},
{"terms": { "field7": [3,4,5]}}
]
}
}
],
"minimum_should_match": 3
}
},
"size": 20
I have to use "minimum_should_match": 3,to meet my requirements(If i remove it I get unrelated results) but when i use it with filter the result gets notthing.Is there any suggestion how to get current result and filter it based on field7?
#Paris I believe you can use filter term query for field7 since you want to apply filter on the result-set from should+must query. So basically this should suffice:
"query": {
"bool": {
"should": [
{
"match_bool_prefix": {
"field1": {
"query": "test",
"fuzziness": "auto",
"boost": 1
}
}
},
{
"match": {
"field2": {
"query": "test",
"boost": 10
}
}
},
{
"exists": {
"field": "field3",
"boost": 15
}
},
{
"exists": {
"field": "field4",
"boost": 10
}
},
{
"match_phrase_prefix": {
"field5": {
"query": ""
}
}
}
],
"must": {
{"match": {"field6": "A"}}
},
"filter": {
{"term" : {"field7" : 3}},
{"term" : {"field7" : 4}},
{"term" : {"field7" : 5}},
}
}
},
"size": 20

Search by child product when search by sku in elastic search query

I have some products below
Id Name SKU isParent
1 A 100 True
2 A1 101 False
3 A2 102 False
4 A3 103 False
5 A4 104 False
6 B 105 True
7 B1 106 False
8 B2 107 False
I have query to find the product by name,SKU.
I want to exclude the product which is IsParent is false when try to search by name but when its exact search by sku then all product need to be search. How to do it?
Search by name is working fine with excluding isParent false products.
My elastic query as below
{
"min_score": 810,
"query": {
"bool": {
"must": [
{
"term": {
"Published": {
"value": "true"
}
}
},
{
"terms": {
"Stores.Id": [
0,
1
]
}
},
{
"bool": {
"must_not": {
"term": {
"IsParentProduct": "false"
}
}
}
},
{
"bool": {
"should": [
{
"match_phrase": {
"Name": {
"query": "BGEBASIC33",
"boost": 100
}
}
},
{
"match": {
"Name": {
"query": "BGEBASIC33",
"boost": 150
}
}
},
{
"match_phrase": {
"ProductCategories.Name.exact": {
"query": "BGEBASIC33",
"boost": 200
}
}
},
{
"match": {
"ProductCategories.Name.exact": {
"query": "BGEBASIC33",
"boost": 300
}
}
},
{
"match_phrase": {
"ParentCategory.Name": {
"query": "BGEBASIC33",
"boost": 1000
}
}
},
{
"match": {
"ParentCategory.Name": {
"query": "BGEBASIC33",
"boost": 750
}
}
},
{
"match_phrase": {
"ShortDescription": {
"query": "BGEBASIC33",
"boost": 5
}
}
},
{
"match": {
"ShortDescription": {
"query": "BGEBASIC33",
"boost": 5
}
}
},
{
"match_phrase": {
"FullDescription": {
"query": "BGEBASIC33",
"boost": 5
}
}
},
{
"match": {
"FullDescription": {
"query": "BGEBASIC33",
"boost": 5
}
}
},
{
"match_phrase": {
"ProductManufacturer.Name.exact": {
"query": "BGEBASIC33",
"boost": 200
}
}
},
{
"match": {
"ProductManufacturer.Name.exact": {
"query": "BGEBASIC33",
"boost": 200
}
}
},
{
"nested": {
"path": "ProductPromoTags",
"query": {
"bool": {
"must": [
{
"bool": {
"should": [
{
"match_phrase": {
"ProductPromoTags.Name": {
"query": "BGEBASIC33",
"boost": 100
}
}
},
{
"match": {
"ProductPromoTags.Name": {
"query": "BGEBASIC33",
"boost": 100
}
}
}
]
}
},
{
"bool": {
"should": [
{
"match_phrase": {
"ProductPromoTags.SystemName": {
"query": "BGEBASIC33",
"boost": 100
}
}
},
{
"match": {
"ProductPromoTags.SystemName": {
"query": "BGEBASIC33",
"boost": 100
}
}
}
]
}
}
]
}
}
}
},
{
"match": {
"Sku": {
"query": "BGEBASIC33",
"boost": 500
}
}
},
{
"match_phrase": {
"Sku": {
"query": "BGEBASIC33",
"boost": 100
}
}
},
{
"nested": {
"path": "SpecificationAttributes",
"query": {
"bool": {
"should": [
{
"match_phrase": {
"SpecificationAttributes.SpecificationAttributeOptions.Name.exact": {
"query": "BGEBASIC33",
"boost": 80
}
}
},
{
"match": {
"SpecificationAttributes.SpecificationAttributeOptions.Name.exact": {
"query": "BGEBASIC33",
"boost": 100
}
}
}
]
}
}
}
}
]
}
}
]
}
},
"from": 0,
"size": 32,
"aggs": {
"PriceRanges": {
"range": {
"field": "FinalPrice",
"ranges": [
{
"from": "0",
"to": "100"
},
{
"from": "101",
"to": "998"
},
{
"from": "999",
"to": "1999"
},
{
"from": "2000",
"to": "2999"
},
{
"from": "3000"
}
]
}
},
"ProductCategoryCustomURL": {
"terms": {
"field": "ProductCategories.CustomURL",
"size": 100
}
},
"ProductManufacturer": {
"terms": {
"field": "ProductManufacturer.Name",
"size": 100
}
},
"SpecificationAttributesfiltered": {
"filter": {
"bool": {
"must": [
]
}
},
"aggs": {
"SpecificationAttributes": {
"nested": {
"path": "SpecificationAttributes"
},
"aggs": {
"Spec_group": {
"terms": {
"field": "SpecificationAttributes.Name",
"size": 100
},
"aggs": {
"Opctions": {
"terms": {
"field": "SpecificationAttributes.SpecificationAttributeOptions.Name",
"size": 100
}
}
}
}
}
}
}
},
"SpecificationAttributesFirstFiltered": {
"filter": {
"bool": {
"must": [
]
}
},
"aggs": {
"SpecificationAttributes": {
"nested": {
"path": "SpecificationAttributes"
},
"aggs": {
"Spec_group": {
"terms": {
"field": "SpecificationAttributes.Name",
"size": 100
},
"aggs": {
"Opctions": {
"terms": {
"field": "SpecificationAttributes.SpecificationAttributeOptions.Name",
"size": 100
}
}
}
}
}
}
}
}
}
}
Main image is parent product.
After image you can see the three round image and sequre box that are separate products that connect with main image product. Child products haveing property "IsChildProduct" that is set as true if its child.
I want to exclude the child products in search as separate product that is working fine in my query. but if user want to search by child product sku,name etc then my query return emty result.
Let me know what should I do to make this working.
You should share the query you have so far, but here is my take. Basically, one of the should clause must match, either by Name with isParent: false or just by SKU:
{
"query": {
"bool": {
"minimum_should_match": 1,
"should": [
{
"bool": {
"must_not": {
"term": {
"isParent": false
}
},
"must": [
{
"match": {
"Name": "xyz_search_term"
}
}
]
}
},
{
"term": {
"Sku": "xyz_search_term"
}
}
]
}
}
}
UPDATE:
{
"query": {
"bool": {
"minimum_should_match": 1,
"should": [
{
"bool": {
"must_not": {
"term": {
"isParent": false
}
},
"must": [
{
"match_phrase": {
"Name": {
"query": "BGEBASIC33",
"boost": 100
}
}
},
{
"match": {
"Name": {
"query": "BGEBASIC33",
"boost": 150
}
}
},
{
"match_phrase": {
"ProductCategories.Name.exact": {
"query": "BGEBASIC33",
"boost": 200
}
}
},
{
"match": {
"ProductCategories.Name.exact": {
"query": "BGEBASIC33",
"boost": 300
}
}
},
{
"match_phrase": {
"ParentCategory.Name": {
"query": "BGEBASIC33",
"boost": 1000
}
}
},
{
"match": {
"ParentCategory.Name": {
"query": "BGEBASIC33",
"boost": 750
}
}
},
{
"match_phrase": {
"ShortDescription": {
"query": "BGEBASIC33",
"boost": 5
}
}
},
{
"match": {
"ShortDescription": {
"query": "BGEBASIC33",
"boost": 5
}
}
},
{
"match_phrase": {
"FullDescription": {
"query": "BGEBASIC33",
"boost": 5
}
}
},
{
"match": {
"FullDescription": {
"query": "BGEBASIC33",
"boost": 5
}
}
},
{
"match_phrase": {
"ProductManufacturer.Name.exact": {
"query": "BGEBASIC33",
"boost": 200
}
}
},
{
"match": {
"ProductManufacturer.Name.exact": {
"query": "BGEBASIC33",
"boost": 200
}
}
},
{
"nested": {
"path": "ProductPromoTags",
"query": {
"bool": {
"must": [
{
"bool": {
"should": [
{
"match_phrase": {
"ProductPromoTags.Name": {
"query": "BGEBASIC33",
"boost": 100
}
}
},
{
"match": {
"ProductPromoTags.Name": {
"query": "BGEBASIC33",
"boost": 100
}
}
}
]
}
},
{
"bool": {
"should": [
{
"match_phrase": {
"ProductPromoTags.SystemName": {
"query": "BGEBASIC33",
"boost": 100
}
}
},
{
"match": {
"ProductPromoTags.SystemName": {
"query": "BGEBASIC33",
"boost": 100
}
}
}
]
}
}
]
}
}
}
},
{
"nested": {
"path": "SpecificationAttributes",
"query": {
"bool": {
"should": [
{
"match_phrase": {
"SpecificationAttributes.SpecificationAttributeOptions.Name.exact": {
"query": "BGEBASIC33",
"boost": 80
}
}
},
{
"match": {
"SpecificationAttributes.SpecificationAttributeOptions.Name.exact": {
"query": "BGEBASIC33",
"boost": 100
}
}
}
]
}
}
}
}
]
}
},
{
"bool": {
"should": [
{
"match": {
"Sku": {
"query": "BGEBASIC33",
"boost": 500
}
}
},
{
"match_phrase": {
"Sku": {
"query": "BGEBASIC33",
"boost": 100
}
}
}
]
}
}
]
}
}
}

Combine elasticsearch bool query with range boost

Combine elasticsearch bool query with range boost
I have a complex bool query as follows. I use a bogus search term dgbdrtgndgfndrtgb to fabricate my example, which should not match anything.
{
"from": 0,
"size": 10,
"query": {
"function_score": {
"boost_mode": "replace",
"query": {
"filtered": {
"filter": {
# ...
},
"query": {
"bool": {
"should": [
{
"match": {
"name.suggest_ngrams": {
"query": "dgbdrtgndgfndrtgb",
"fuzziness": "AUTO",
"prefix_length": 1,
"operator": "AND",
"boost": 10
}
}
},
{
"multi_match": {
"query": "dgbdrtgndgfndrtgb",
"fields": [
"name.untouched_lowercase"
],
"boost": 5
}
},
{
"query_string": {
"fields": [
"name.suggest"
],
"query": "dgbdrtgndgfndrtgb*",
"boost": 10
}
},
{
"query_string": {
"fields": [
"name.suggest"
],
"query": "dgbdrtgndgfndrtgb",
"boost": 10
}
},
{
"match": {
"first_word": {
"query": "dgbdrtgndgfndrtgb",
"operator": "AND",
"boost": 10
}
}
},
{
"match": {
"name": {
"query": "dgbdrtgndgfndrtgb",
"operator": "AND",
"boost": 5
}
}
}
]
}
}
}
}
}
}
}
This works well. Now, for any of those matches, I want to add a boost where the name field has fewer than 2 words. In other words, boost single-word matches or sort them to the top of the result set.
So I tried adding a range boost like this:
{
"from": 0,
"size": 10,
"query": {
"function_score": {
"boost_mode": "replace",
"query": {
"filtered": {
"filter": {
# ...
},
"query": {
"bool": {
"should": [
{
"match": {
"name.suggest_ngrams": {
"query": "dgbdrtgndgfndrtgb",
"fuzziness": "AUTO",
"prefix_length": 1,
"operator": "AND",
"boost": 10
}
}
},
{
"multi_match": {
"query": "dgbdrtgndgfndrtgb",
"fields": [
"name.untouched_lowercase"
],
"boost": 5
}
},
{
"query_string": {
"fields": [
"name.suggest"
],
"query": "dgbdrtgndgfndrtgb*",
"boost": 10
}
},
{
"query_string": {
"fields": [
"name.suggest"
],
"query": "dgbdrtgndgfndrtgb",
"boost": 10
}
},
{
"match": {
"first_word": {
"query": "dgbdrtgndgfndrtgb",
"operator": "AND",
"boost": 10
}
}
},
{
"match": {
"name": {
"query": "dgbdrtgndgfndrtgb",
"operator": "AND",
"boost": 5
}
}
},
{
"range": {
"name.word_count": {
"lt": 2,
"boost": 40
}
}
}
]
}
}
}
}
}
}
}
This sorts things like I want, but it also returns single-word matches which do not match the search term dgbdrtgndgfndrtgb.
Is there a way to only boost single-word matches, which also match the search term? I've tried lowering the boost value, which breaks the desired sorting when using a valid (found) search term.
It seems like there should be a way to AND the entire bool query with the range boost. I've tried various permutations to achieve this with no luck and the docs are less than helpful.
One caveat: I cannot use scripting as the index is hosted on AWS which doesn't support it.
Any advice is appreciated.
After sleeping on the problem, it hit me that it is just Boolean logic. So, I came up with this solution that works perfectly, wherein I wrapped the working query logic in a must tag and put the range boost in a should tag.
{
"from": 0,
"size": 10,
"query": {
"function_score": {
"boost_mode": "replace",
"query": {
"filtered": {
"filter": {
# ...
},
"query": {
"bool": {
"must": {
"bool": {
"should": [
{
"match": {
"name.suggest_ngrams": {
"query": "dgbdrtgndgfndrtgb",
"fuzziness": "AUTO",
"prefix_length": 1,
"operator": "AND",
"boost": 10
}
}
},
{
"multi_match": {
"query": "dgbdrtgndgfndrtgb",
"fields": [
"name.untouched_lowercase"
],
"boost": 5
}
},
{
"query_string": {
"fields": [
"name.suggest"
],
"query": "dgbdrtgndgfndrtgb*",
"boost": 10
}
},
{
"query_string": {
"fields": [
"name.suggest"
],
"query": "dgbdrtgndgfndrtgb",
"boost": 10
}
},
{
"match": {
"first_word": {
"query": "dgbdrtgndgfndrtgb",
"operator": "AND",
"boost": 10
}
}
},
{
"match": {
"name": {
"query": "dgbdrtgndgfndrtgb",
"operator": "AND",
"boost": 5
}
}
}
]
}
},
"should": {
"range": {
"name.word_count": {
"lt": 2,
"boost": 40
}
}
}
}
}
}
}
}
}
}
Yay!

Elasticsearch - give negative boost to documents without a certain field

I'm working on a query, the basic filtered multi match query is working as planned, it returns the documents i want.
The issue is that a want to boost results which have a certain string field with ex. 0.5, or in this example give results which don't have this field 'traded_as' a negative boost of 1.0.
Cannot get the filter - boost - must - exists/missing to work as i want.
It this the correct approach on this issue?
Using elasticsearch 1.5.2
{
"query": {
"filtered": {
"query": {
"multi_match": {
"query": "something",
"fields": ["title", "url", "description"]
}
},
"filter": {
"bool": {
"must": {
"missing": {
"field": "marked_for_deletion"
}
}
}
}
}
},
"boosting": {
"positive": {
"filter": {
"bool": {
"must": {
"exists": {
"field": "traded_as"
}
}
}
}
},
"negative": {
"filter": {
"bool": {
"must": {
"missing": {
"field": "traded_as"
}
}
}
}
},
"negative_boost": 1.0
}
}
You cannot have the desired result. As stated in the doc for boosting query :
Unlike the "NOT" clause in bool query, this still selects documents that contain undesirable terms, but reduces their overall score.
{
"query": {
"boosting": {
"positive": [{
"filtered": {
"query": {
"multi_match": {
"query": "something",
"fields": ["title", "url", "description"]
}
},
"filter": {
"bool": {
"must": [{
"missing": {
"field": "marked_for_deletion"
}
}]
}
}
}
}],
"negative": [{
"filtered": {
"filter": {
"missing": {
"field": "traded_as"
}
}
}
}],
"negative_boost": 1.0
}
}
}
So you'll still have some irrelevant documents, but matching documents will have a better score. You won't have any boost on traded_as presence that way. For this you should have a look at function score http://www.elastic.co/guide/en/elasticsearch/reference/current/query-dsl-function-score-query.html#_using_function_score
You would have something like
{
"query": {
"function_score": {
"query": {
"filtered": {
"query": {
"multi_match": {
"query": "something",
"fields": ["title", "url", "description"]
}
},
"filter": {
"bool": {
"must": {
"missing": {
"field": "marked_for_deletion"
}
}
}
}
}
},
"functions": [{
"filter": {
"exists": {
"field": "traded_as"
}
},
"boost_factor": 2
}, {
"filter": {
"missing": {
"field": "traded_as"
}
},
"boost_factor": 0.5
}],
"score_mode": "first",
"boost_mode": "multiply"
}
}
}

Using Elasticsearch, how do I do a filtered query on both my document properties and nested document properties?

Here is an example document source.
{
"tags": [
"meow",
"cats",
"feline"
],
"visible": 1,
"for_sale": "y",
"title": "Cat Meow",
"stock": [{
"department": "mens",
"size": "small"
}, {
"department": "mens",
"size": "medium"
}]
}
I want to find documents that are 'stock.department=mens' and 'stock.size=medium' and also are 'for_sale=y'
Here is the query that I've come up with so far. I can't figure out how to filter by for_sale=y.
{
"size": 5,
"query": {
"filtered": {
"query": {
"multi_match": {
"fields": ["title", "tags"],
"query": "cat"
}
},
"filter": {
"nested": {
"path": "stock",
"filter": {
"bool": {
"must": [{
"term": {
"stock.size": "medium"
}
}, {
"term": {
"stock.department": "mens"
}
}]
}
}
}
}
}
}
}
This is what I've come up with. If anyone has any critiques or improvements please share them.
{
"size": 5,
"query": {
"filtered": {
"query": {
"multi_match": {
"fields": ["title", "tags"],
"query": "cat"
}
},
"filter": {
"bool": {
"must": [{
"term": {
"for_sale": "y"
}
}, {
"term": {
"visible": 1
}
}, {
"nested": {
"path": "stock",
"filter": {
"bool": {
"must": [{
"term": {
"stock.size": "medium"
}
}, {
"term": {
"stock.department": "mens"
}
}]
}
}
}
}]
}
}
}
}
}

Resources