Terms set query

With a terms set query, you can search for documents that match a minimum number of exact terms in a specified field. A terms_set query is similar to a terms query, except that you can specify the minimum number of matching terms that are required in order to return a document. You can specify this number either in a field in the index or with a script.

As an example, consider an index that contains names of students and classes those students have taken. When setting up the mapping for this index, you need to provide a numeric field that specifies the minimum number of matching terms that are required in order to return a document:

  1. PUT students
  2. {
  3. "mappings": {
  4. "properties": {
  5. "name": {
  6. "type": "keyword"
  7. },
  8. "classes": {
  9. "type": "keyword"
  10. },
  11. "min_required": {
  12. "type": "integer"
  13. }
  14. }
  15. }
  16. }

copy

Next, index two documents that correspond to students:

  1. PUT students/_doc/1
  2. {
  3. "name": "Mary Major",
  4. "classes": [ "CS101", "CS102", "MATH101" ],
  5. "min_required": 2
  6. }

copy

  1. PUT students/_doc/2
  2. {
  3. "name": "John Doe",
  4. "classes": [ "CS101", "MATH101", "ENG101" ],
  5. "min_required": 2
  6. }

copy

Now search for students who have taken at least two of the following classes: CS101, CS102, MATH101:

  1. GET students/_search
  2. {
  3. "query": {
  4. "terms_set": {
  5. "classes": {
  6. "terms": [ "CS101", "CS102", "MATH101" ],
  7. "minimum_should_match_field": "min_required"
  8. }
  9. }
  10. }
  11. }

copy

The response contains both documents:

  1. {
  2. "took" : 44,
  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" : 1.4544616,
  16. "hits" : [
  17. {
  18. "_index" : "students",
  19. "_id" : "1",
  20. "_score" : 1.4544616,
  21. "_source" : {
  22. "name" : "Mary Major",
  23. "classes" : [
  24. "CS101",
  25. "CS102",
  26. "MATH101"
  27. ],
  28. "min_required" : 2
  29. }
  30. },
  31. {
  32. "_index" : "students",
  33. "_id" : "2",
  34. "_score" : 0.5013843,
  35. "_source" : {
  36. "name" : "John Doe",
  37. "classes" : [
  38. "CS101",
  39. "MATH101",
  40. "ENG101"
  41. ],
  42. "min_required" : 2
  43. }
  44. }
  45. ]
  46. }
  47. }

To specify the minimum number of terms a document should match with a script, provide the script in the minimum_should_match_script field:

  1. GET students/_search
  2. {
  3. "query": {
  4. "terms_set": {
  5. "classes": {
  6. "terms": [ "CS101", "CS102", "MATH101" ],
  7. "minimum_should_match_script": {
  8. "source": "Math.min(params.num_terms, doc['min_required'].value)"
  9. }
  10. }
  11. }
  12. }
  13. }

copy

Parameters

The query accepts the name of the field (<field>) as a top-level parameter:

  1. GET _search
  2. {
  3. "query": {
  4. "terms_set": {
  5. "<field>": {
  6. "terms": [ "term1", "term2" ],
  7. ...
  8. }
  9. }
  10. }
  11. }

copy

The <field> accepts the following parameters. All parameters except terms are optional.

ParameterData typeDescription
termsArray of stringsThe array of terms to search for in the field specified in <field>. A document is returned in the results only if the required number of terms matches the document’s field values exactly, with the correct spacing and capitalization.
minimum_should_match_fieldStringThe name of the numeric field that specifies the number of matching terms required in order to return a document in the results.
minimum_should_match_scriptStringA script that returns the number of matching terms required in order to return a document in the results.