In many places of the elasticsearch dsl query grammar documentation, the wrapper json queries are skipped out in explanations probably to reduce documentation size. But its been confusing as I've been navigating the documentation. What are officially the rules for what can or should go where in a json query? In other words, I'm trying to find the standard or pattern common across all elastic queries because I need to build an internal api to query elastic. Is there a template that contains all of the grammar components "query': {}
inside a "bool":{}
or a filter
etc. in which I can just fill in the relevant parts and it still runs?

- 8,138
- 15
- 69
- 120
1 Answers
I also find Elastic's DSL structure confusing, but after running hundreds of queries you get used to it.
Here are a few (full) examples of different types of queries, hopefully this will help clear some questions you may have, feel free to add scenarios in a comment and I'll add more examples.
This is how a standard query looks like:
{
"query": {
"bool": {
"must": {
"match": {
"message": "abcd"
}
}
}
}
}
However, this is how a filtered query looks like, you'll notice a change in structure when filtering elasticsearch:
{
"query": {
"filtered": {
"filter": {
"term": {
"message": "abcd"
}
}
}
}
}
(Read more about the difference between Filters and Queries)
Here's how a query that has both filters and queries look like:
{
"query": {
"filtered": {
"filter": {
"term": {
"message": "abcd"
}
},
"query": {
"bool": {
"must": {
"match": {
"message2": "bbbb"
}
}
}
}
}
}
}
Here's how you run a filter with multiple conditions:
{
"query": {
"filtered": {
"filter": {
"and": [
{
"term": {
"message": "abcd"
}
},
{
"term": {
"message2": "abcdd"
}
}
]
}
}
}
}
And a more complex filter:
{
"query": {
"filtered": {
"filter": {
"and": [
{
"term": {
"message": "abcd"
}
},
{
"term": {
"message2": "abcdd"
}
},
{
"or": [
{
"term": {
"message3": "abcddx"
}
},
{
"term": {
"message4": "abcdd2"
}
}
]
}
]
}
}
}
}
Simple query with aggregations:
{
"query": {
"filtered": {
"filter": {
"term": {
"message": "abcd"
}
}
}
},
"aggs": {
"any_name_will_work_here": {
"max": {
"field": "metric1"
}
}
}
}
A query_string
query:
{
"query": {
"query_string": {
"default_field": "message",
"query": "this AND that"
}
}
}
Some other things to consider when using the DSL:
- You can add a
size
parameter at the top level (above the query) which will determine the amount of results to return. If you want JUST doc counts you can use"size": 0
which will not get any results, just the meta data. - However, when using
aggs
the size parameter has a twist, setting"size": 0
inside theaggs
field will tell ES to get ALL aggregation buckets - The DSL structure has exceptions, in my examples I usually used
terms
, butrange
for example has a bit of a different structure.

- 1
- 1

- 7,332
- 23
- 71
- 116
-
Thank you. So in Filters, you can't have musts, shoulds, and must_nots? You can only have the AND OR etc? If that is the case, I have 2 questions. What's the difference between the AND ORs in Filters and the Bools (Must, should etc.) in queries? Also what about the query_string query? Can that go in a filter or that must be in the query? It looks like, the filter can also take queries. Which makes this insanley confusing. – Horse Voice Aug 03 '15 at 20:21
-
Yes, filters take only `and`/`or` and queries take `must`/`should` and they are exactly the same (and=must, or=should). The reason you should choose queries over filters is in that SO answer I linked to earlier. The query_string goes only under the query part and that's also an exception in the 'standard' query structure. I'll add an example for it now. You can nest a 'query' under a 'filter' which basically allows you to combine the abilities of queries within the same filtered query. It's complicated, I know and you're right ;( – Or Weinberger Aug 03 '15 at 20:24
-
you mean to say that I should use filters over queries right? Due to the caching of filters? – Horse Voice Aug 03 '15 at 20:29
-
Yes. Filtered queries are cached and are also more efficient since ES does not need to calculate a score for them. However you might want to get a score for your results, for example if you're using a full text search on analyzed fields. – Or Weinberger Aug 03 '15 at 20:31
-
Thanks! lets say if I don't care for the score at this time and decide to use filters, can't I just wrap the filter into a query? that would then give me the score if I need it or am I missing something here? – Horse Voice Aug 03 '15 at 20:38
-
Not sure I follow, if you don't care about scores and just want, for example, exact matches on certain fields - use filters (like my second example above). If later on you decide you do care about scores, you'll need to adjust your query to use the `{ "bool": { "must/should": { "match": "" } } }` – Or Weinberger Aug 03 '15 at 20:41
-
What I mean to say is, Instead of converting the internal details of the boolean logic to use the query equivalent must/shoulds, can't I just wrap the entire filter inside of a `"query":{}` ? That would give the scores then wouldnt it? – Horse Voice Aug 03 '15 at 20:48
-
Also, it's worth noting that in ES 2.0, the Query DSL will be [completely overhauled](https://www.elastic.co/guide/en/elasticsearch/reference/master/_query_dsl.html) and queries and filters will be "merged" together. – Val Aug 04 '15 at 04:28