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.
boostFloating-pointA floating-point value that specifies the weight of this field toward the relevance score. Values above 1.0 increase the field’s relevance. Values between 0.0 and 1.0 decrease the field’s relevance. Default is 1.0.