Elasticsearch query DSL
last updated 2013-01
update 2026 - written for Elasticsearch 0.20 (2013). the ideas hold, but a lot of the API doesn't: the filtered query, the and/or/not and missing filters and the field query were removed by 5.0 - it's all a bool query with must/should/must_not/filter clauses now, plus exists. filters and queries are no longer separate things either
ES's query DSL is a language for specifying queries in JSON
this is by far not exhaustive documentation, it's just stuff i use the most; see the official documentation for more. especially the boosting and scoring functionality is not documented here to a proper extent
queries
match, multi_match
the match queries accept, analyze, and construct a query out of text/numeric/date. the match family of queries does not go through a "query parsing" process. it doesn't support field name prefixes, wildcard characters, or other "advanced" features
here, message is the name of the field to match in (can also be _all):
{
"match" : {
"message" : "this is a test"
}
}
by default, terms are OR'ed; to AND them:
{
"match" : {
"message" : {
"query" : "this is a test",
"operator" : "and"
}
}
}
to match a phrase:
{
"match_phrase" : {
"message" : "this is a test"
}
}
or using the last word as prefix (the "as you type" search):
{
"match_phrase_prefix" : {
"message" : "this is a test"
}
}
to match in multiple fields, with optional boosting, use:
{
"multi_match" : {
"query" : "this is a test",
"fields" : [ "subject^2", "message" ]
}
}
where matches in subject are "twice as important" as matches in message
bool
the bool query provides a Boolean combination of queries with typed occurrence:
- must - clause must appear in matching documents
- should - should appear; if no
mustclause is provided, at least oneshouldclause must be matched; you can also specify theminimum_number_should_matchparameter - must_not appear
{
"bool" : {
"must" : {
"term" : { "user" : "kimchy" }
},
"must_not" : {
"range" : {
"age" : { "from" : 10, "to" : 20 }
}
},
"should" : [
{
"term" : { "tag" : "wow" }
},
{
"term" : { "tag" : "elasticsearch" }
}
],
"minimum_number_should_match" : 1,
"boost" : 1.0
}
}
boosting
boosting can be used to promote or demote search results:
{
"boosting" : {
"positive" : {
"term" : {
"field1" : "value1"
}
},
"negative" : {
"term" : {
"field2" : "value2"
}
},
"negative_boost" : 0.2
}
}
ids
match by ID:
{
"ids" : {
"type" : "my_type",
"values" : ["1", "4", "100"]
}
}
note: the type field is optional, and may contain an array of values
field
query only on a specified field (equivalent of query_string with default_field):
{
"field" : {
"name.first" : "+something -else"
}
}
filtered
filters results of a query; may be much faster than querying, as no scoring is done, and may be cached:
{
"filtered" : {
"query" : {
"term" : { "tag" : "wow" }
},
"filter" : {
"range" : {
"age" : { "from" : 10, "to" : 20 }
}
}
}
}
query_string
uses the query parser in order to parse its content
{
"query_string" : {
"default_field" : "content",
"query" : "this AND that OR thus"
}
}
parameters
query- actual query to be parseddefault_field- default field for query terms (if no prefix field specified); default is theindex.query.default_fieldsetting, which defaults to_allfields- run query against multiple fields (provided as array):"fields" : ["content", "name"]- optionally with boosting:
"fields" : ["content", "name^5"] - wildcards may be used for fields:
"fields" : ["city.*"]if the document contains the objectcity - to check for existence or nonexistence of fields, use:
_exists_:field1and_missing_:field
default_operator- default operator used (if none explicitly specified); e.g. with default operatorOR, the query "capital of Hungary" is translated to "capital OR of OR Hungary"; default isORallow_leading_wildcard- are*or?allowed as the first character? defaulttruelowercase_expanded_terms- should terms of wildcard, prefix, fuzzy, and range queries be automatically lower-cased? (since they are not analyzed); defaulttrueboost- boost value of the query; default1.0minimum_should_match- percent value ("20%") controlling how many "should" clauses in the resulting boolean query should matchlenient- iftrue, format based failures (like providing text to a numeric field) are ignored
range
matches documents by a provided range. for string fields, the TermRangeQuery is used, while for number/date fields, the query is a NumericRangeQuery
{
"range" : {
"age" : {
"from" : 10,
"to" : 20,
"include_lower" : true,
"include_upper": false,
"boost" : 2.0
}
}
}
you can also use the following abbreviations:
gt=from+include_lower=falsegte=from+include_lower=truelt=to+include_upper=falselte=to+include_upper=true
term, terms
matches documents that have fields that contain a term (not analyzed)
{ "term" : { "user" : "kimchy" } }
{ "term" : { "user" : { "term" : "kimchy", "boost" : 2.0 } } }
filters
filters can be a great candidate for caching. caching the result of a filter doesn't require a lot of memory, and will cause other queries executing against the same filter (same parameters) to be blazingly fast. esp. term, terms, prefix, and range filters are cached by default and are recommended to use (compared to the equivalent query version)
and, or, not
matches documents using the AND operator on other queries, more performant than the bool filter
these filters are not cached by default
{
"filtered" : {
"query" : {
"term" : { "name.first" : "shay" }
},
"filter" : {
"and" : [
{
"range" : {
"postDate" : {
"from" : "2010-03-01",
"to" : "2010-04-01"
}
}
},
{
"prefix" : { "name.second" : "ba" }
}
]
}
}
}
to cache the results of the filter:
{
"filtered" : {
"query" : {
"term" : { "name.first" : "shay" }
},
"filter" : {
"or" : {
"filters" : [
{
"term" : { "name.second" : "banon" }
},
{
"term" : { "name.nick" : "kimchy" }
}
],
"_cache" : true
}
}
}
}
bool
matches documents matching Boolean combinations of other queries. similar to Boolean queries, but clauses are filters:
{
"filtered" : {
"query" : {
"queryString" : {
"default_field" : "message",
"query" : "elasticsearch"
}
},
"filter" : {
"bool" : {
"must" : {
"term" : { "tag" : "wow" }
},
"must_not" : {
"range" : {
"age" : { "from" : 10, "to" : 20 }
}
},
"should" : [
{
"term" : { "tag" : "sometag" }
},
{
"term" : { "tag" : "sometagtag" }
}
]
}
}
}
}
exists, missing
filters documents where a specific field has a value in them (exists), or has no value in them (missing)
{
"constant_score" : {
"filter" : {
"exists" : { "field" : "user" }
}
}
}
range, numeric_range
unlike the range query, the range filter is cached; see the range query for available parameters
{
"constant_score" : {
"filter" : {
"range" : {
"age" : {
"from" : "10",
"to" : "20",
"include_lower" : true,
"include_upper" : false
}
}
}
}
}
the numeric_range filter loads relevant fields to memory and checks the numeric range; this requires more memory, but may be significantly faster
unlike range, numeric_range filter results are not cached by default. set _cache to true to do so. but if the filter is reused, it's advisable to simply use the range filter
query
wraps a query to be used as a filter:
{
"constantScore" : {
"filter" : {
"query" : {
"query_string" : {
"query" : "this AND that OR thus"
}
}
}
}
}
this is not cached by default; to allow caching (note that the format differs a bit from other filters):
{
"constantScore" : {
"filter" : {
"fquery" : {
"query" : {
"query_string" : {
"query" : "this AND that OR thus"
}
},
"_cache" : true
}
}
}
}
term, terms
filters documents that have fields that contain a term (not analyzed), and is cached by default:
{
"constant_score" : {
"filter" : {
"term" : { "user" : "kimchy"}
}
}
}
the terms filter simply accepts multiple terms, matching documents containing any of the terms; if you want to match all of the terms, use execution=and:
{
"constant_score" : {
"filter" : {
"terms" : {
"user" : ["kimchy", "elasticsearch"],
"execution" : "and"
}
}
}
}