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:
PUT students
{
"mappings": {
"properties": {
"name": {
"type": "keyword"
},
"classes": {
"type": "keyword"
},
"min_required": {
"type": "integer"
}
}
}
}
Next, index two documents that correspond to students:
PUT students/_doc/1
{
"name": "Mary Major",
"classes": [ "CS101", "CS102", "MATH101" ],
"min_required": 2
}
PUT students/_doc/2
{
"name": "John Doe",
"classes": [ "CS101", "MATH101", "ENG101" ],
"min_required": 2
}
Now search for students who have taken at least two of the following classes: CS101
, CS102
, MATH101
:
GET students/_search
{
"query": {
"terms_set": {
"classes": {
"terms": [ "CS101", "CS102", "MATH101" ],
"minimum_should_match_field": "min_required"
}
}
}
}
The response contains both documents:
{
"took" : 44,
"timed_out" : false,
"_shards" : {
"total" : 1,
"successful" : 1,
"skipped" : 0,
"failed" : 0
},
"hits" : {
"total" : {
"value" : 2,
"relation" : "eq"
},
"max_score" : 1.4544616,
"hits" : [
{
"_index" : "students",
"_id" : "1",
"_score" : 1.4544616,
"_source" : {
"name" : "Mary Major",
"classes" : [
"CS101",
"CS102",
"MATH101"
],
"min_required" : 2
}
},
{
"_index" : "students",
"_id" : "2",
"_score" : 0.5013843,
"_source" : {
"name" : "John Doe",
"classes" : [
"CS101",
"MATH101",
"ENG101"
],
"min_required" : 2
}
}
]
}
}
To specify the minimum number of terms a document should match with a script, provide the script in the minimum_should_match_script
field:
GET students/_search
{
"query": {
"terms_set": {
"classes": {
"terms": [ "CS101", "CS102", "MATH101" ],
"minimum_should_match_script": {
"source": "Math.min(params.num_terms, doc['min_required'].value)"
}
}
}
}
}
Parameters
The query accepts the name of the field (<field>
) as a top-level parameter:
GET _search
{
"query": {
"terms_set": {
"<field>": {
"terms": [ "term1", "term2" ],
...
}
}
}
}
The <field>
accepts the following parameters. All parameters except terms
are optional.
Parameter | Data type | Description |
---|---|---|
terms | Array of strings | The 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_field | String | The 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_script | String | A script that returns the number of matching terms required in order to return a document in the results. |