Minimum should match

The minimum_should_match parameter can be used for full-text search and specifies the minimum number of terms a document must match to be returned in search results.

The following example requires a document to match at least two out of three search terms in order to be returned as a search result:

  1. GET /shakespeare/_search
  2. {
  3. "query": {
  4. "match": {
  5. "text_entry": {
  6. "query": "prince king star",
  7. "minimum_should_match": "2"
  8. }
  9. }
  10. }
  11. }

In this example, the query has three optional clauses that are combined with an OR, so the document must match either prince, king, or star.

Valid values

You can specify the minimum_should_match parameter as one of the following values.

Value typeExampleDescription
Non-negative integer2A document must match this number of optional clauses.
Negative integer-1A document must match the total number of optional clauses minus this number.
Non-negative percentage70%A document must match this percentage of the total number of optional clauses. The number of clauses to match is rounded down to the nearest integer.
Negative percentage-30%A document can have this percentage of the total number of optional clauses that do not match. The number of clauses a document is allowed to not match is rounded down to the nearest integer.
Combination2<75%Expression in the n<p% format. If the number of optional clauses is less than or equal to n, the document must match all optional clauses. If the number of optional clauses is greater than n, then the document must match the p percentage of optional clauses.
Multiple combinations3<-1 5<50%More than one combination separated by a space. Each condition applies to the number of optional clauses that is greater than the number on the left of the < sign. In this example, if there are three or fewer optional clauses, the document must match all of them. If there are four or five optional clauses, the document must match all but one of them. If there are 6 or more optional clauses, the document must match 50% of them.

Let n be the number of optional clauses a document must match. When n is calculated as a percentage, if n is less than 1, then 1 is used. If n is greater than the number of optional clauses, the number of optional clauses is used.

Using the parameter in Boolean queries

A Boolean query lists optional clauses in the should clause and required clauses in the must clause. Optionally, it can contain a filter clause to filter results.

Consider an example index containing the following five documents:

  1. PUT testindex/_doc/1
  2. {
  3. "text": "one OpenSearch"
  4. }

copy

  1. PUT testindex/_doc/2
  2. {
  3. "text": "one two OpenSearch"
  4. }

copy

  1. PUT testindex/_doc/3
  2. {
  3. "text": "one two three OpenSearch"
  4. }

copy

  1. PUT testindex/_doc/4
  2. {
  3. "text": "one two three four OpenSearch"
  4. }

copy

  1. PUT testindex/_doc/5
  2. {
  3. "text": "OpenSearch"
  4. }

copy

The following query contains four optional clauses:

  1. GET testindex/_search
  2. {
  3. "query": {
  4. "bool": {
  5. "must": [
  6. {
  7. "match": {
  8. "text": "OpenSearch"
  9. }
  10. }
  11. ],
  12. "should": [
  13. {
  14. "match": {
  15. "text": "one"
  16. }
  17. },
  18. {
  19. "match": {
  20. "text": "two"
  21. }
  22. },
  23. {
  24. "match": {
  25. "text": "three"
  26. }
  27. },
  28. {
  29. "match": {
  30. "text": "four"
  31. }
  32. }
  33. ],
  34. "minimum_should_match": "80%"
  35. }
  36. }
  37. }

copy

Because minimum_should_match is specified as 80%, the number of optional clauses to match is calculated as 4 · 0.8 = 3.2 and then rounded down to 3. Therefore, the results contain documents that match at least three clauses:

  1. {
  2. "took": 40,
  3. "timed_out": false,
  4. "_shards": {
  5. "total": 1,
  6. "successful": 1,
  7. "skipped": 0,
  8. "failed": 0
  9. },
  10. "hits": {
  11. "total": {
  12. "value": 2,
  13. "relation": "eq"
  14. },
  15. "max_score": 2.494999,
  16. "hits": [
  17. {
  18. "_index": "testindex",
  19. "_id": "4",
  20. "_score": 2.494999,
  21. "_source": {
  22. "text": "one two three four OpenSearch"
  23. }
  24. },
  25. {
  26. "_index": "testindex",
  27. "_id": "3",
  28. "_score": 1.5744598,
  29. "_source": {
  30. "text": "one two three OpenSearch"
  31. }
  32. }
  33. ]
  34. }
  35. }

Now specify minimum_should_match as -20%:

  1. GET testindex/_search
  2. {
  3. "query": {
  4. "bool": {
  5. "must": [
  6. {
  7. "match": {
  8. "text": "OpenSearch"
  9. }
  10. }
  11. ],
  12. "should": [
  13. {
  14. "match": {
  15. "text": "one"
  16. }
  17. },
  18. {
  19. "match": {
  20. "text": "two"
  21. }
  22. },
  23. {
  24. "match": {
  25. "text": "three"
  26. }
  27. },
  28. {
  29. "match": {
  30. "text": "four"
  31. }
  32. }
  33. ],
  34. "minimum_should_match": "-20%"
  35. }
  36. }
  37. }

copy

The number of non-matching optional clauses that a document can have is calculated as 4 · 0.2 = 0.8 and rounded down to 0. Thus, the results contain only one document that matches all optional clauses:

  1. {
  2. "took": 41,
  3. "timed_out": false,
  4. "_shards": {
  5. "total": 1,
  6. "successful": 1,
  7. "skipped": 0,
  8. "failed": 0
  9. },
  10. "hits": {
  11. "total": {
  12. "value": 1,
  13. "relation": "eq"
  14. },
  15. "max_score": 2.494999,
  16. "hits": [
  17. {
  18. "_index": "testindex",
  19. "_id": "4",
  20. "_score": 2.494999,
  21. "_source": {
  22. "text": "one two three four OpenSearch"
  23. }
  24. }
  25. ]
  26. }
  27. }

Note that specifying a positive percentage (80%) and negative percentage (-20%) did not result in the same number of optional clauses a document must match because, in both cases, the result was rounded down. If the number of optional clauses were, for example, 5, then both 80% and -20% would have produced the same number of optional clauses a document must match (4).

Default minimum_should_match value

If a query contains a must or filter clause, the default minimum_should_match value is 0. For example, the following query searches for documents that match OpenSearch and 0 optional should clauses:

  1. GET testindex/_search
  2. {
  3. "query": {
  4. "bool": {
  5. "must": [
  6. {
  7. "match": {
  8. "text": "OpenSearch"
  9. }
  10. }
  11. ],
  12. "should": [
  13. {
  14. "match": {
  15. "text": "one"
  16. }
  17. },
  18. {
  19. "match": {
  20. "text": "two"
  21. }
  22. },
  23. {
  24. "match": {
  25. "text": "three"
  26. }
  27. },
  28. {
  29. "match": {
  30. "text": "four"
  31. }
  32. }
  33. ]
  34. }
  35. }
  36. }

copy

This query returns all five documents in the index:

  1. {
  2. "took": 34,
  3. "timed_out": false,
  4. "_shards": {
  5. "total": 1,
  6. "successful": 1,
  7. "skipped": 0,
  8. "failed": 0
  9. },
  10. "hits": {
  11. "total": {
  12. "value": 5,
  13. "relation": "eq"
  14. },
  15. "max_score": 2.494999,
  16. "hits": [
  17. {
  18. "_index": "testindex",
  19. "_id": "4",
  20. "_score": 2.494999,
  21. "_source": {
  22. "text": "one two three four OpenSearch"
  23. }
  24. },
  25. {
  26. "_index": "testindex",
  27. "_id": "3",
  28. "_score": 1.5744598,
  29. "_source": {
  30. "text": "one two three OpenSearch"
  31. }
  32. },
  33. {
  34. "_index": "testindex",
  35. "_id": "2",
  36. "_score": 0.91368985,
  37. "_source": {
  38. "text": "one two OpenSearch"
  39. }
  40. },
  41. {
  42. "_index": "testindex",
  43. "_id": "1",
  44. "_score": 0.4338556,
  45. "_source": {
  46. "text": "one OpenSearch"
  47. }
  48. },
  49. {
  50. "_index": "testindex",
  51. "_id": "5",
  52. "_score": 0.11964063,
  53. "_source": {
  54. "text": "OpenSearch"
  55. }
  56. }
  57. ]
  58. }
  59. }

However, if you omit the must clause, then the query searches for documents that match one optional should clause:

  1. GET testindex/_search
  2. {
  3. "query": {
  4. "bool": {
  5. "should": [
  6. {
  7. "match": {
  8. "text": "one"
  9. }
  10. },
  11. {
  12. "match": {
  13. "text": "two"
  14. }
  15. },
  16. {
  17. "match": {
  18. "text": "three"
  19. }
  20. },
  21. {
  22. "match": {
  23. "text": "four"
  24. }
  25. }
  26. ]
  27. }
  28. }
  29. }

copy

The results contain only four documents that match at least one of the optional clauses:

  1. {
  2. "took": 19,
  3. "timed_out": false,
  4. "_shards": {
  5. "total": 1,
  6. "successful": 1,
  7. "skipped": 0,
  8. "failed": 0
  9. },
  10. "hits": {
  11. "total": {
  12. "value": 4,
  13. "relation": "eq"
  14. },
  15. "max_score": 2.426633,
  16. "hits": [
  17. {
  18. "_index": "testindex",
  19. "_id": "4",
  20. "_score": 2.426633,
  21. "_source": {
  22. "text": "one two three four OpenSearch"
  23. }
  24. },
  25. {
  26. "_index": "testindex",
  27. "_id": "3",
  28. "_score": 1.4978898,
  29. "_source": {
  30. "text": "one two three OpenSearch"
  31. }
  32. },
  33. {
  34. "_index": "testindex",
  35. "_id": "2",
  36. "_score": 0.8266785,
  37. "_source": {
  38. "text": "one two OpenSearch"
  39. }
  40. },
  41. {
  42. "_index": "testindex",
  43. "_id": "1",
  44. "_score": 0.3331056,
  45. "_source": {
  46. "text": "one OpenSearch"
  47. }
  48. }
  49. ]
  50. }
  51. }