paskvilwiki

up: databases & search

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 must clause is provided, at least one should clause must be matched; you can also specify the minimum_number_should_match parameter
  • 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 parsed
  • default_field - default field for query terms (if no prefix field specified); default is the index.query.default_field setting, which defaults to _all
  • fields - 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 object city
    • to check for existence or nonexistence of fields, use: _exists_:field1 and _missing_:field
  • default_operator - default operator used (if none explicitly specified); e.g. with default operator OR, the query "capital of Hungary" is translated to "capital OR of OR Hungary"; default is OR
  • allow_leading_wildcard - are * or ? allowed as the first character? default true
  • lowercase_expanded_terms - should terms of wildcard, prefix, fuzzy, and range queries be automatically lower-cased? (since they are not analyzed); default true
  • boost - boost value of the query; default 1.0
  • minimum_should_match - percent value ("20%") controlling how many "should" clauses in the resulting boolean query should match
  • lenient - if true, 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=false
  • gte = from + include_lower=true
  • lt = to + include_upper=false
  • lte = 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"
            }
        }
    }
}