# Formal spec for Query DSL

**URL:** <https://discuss.elastic.co/t/formal-spec-for-query-dsl/2820>\
**Category:** Elasticsearch\
**Created:** [February 19, 2010, 3:48pm UTC](https://discuss.elastic.co/t/formal-spec-for-query-dsl/2820 "2010-02-19T15:48:40Z")\
**Posts on this page:** 6\
**Page:** 1

<div class="post-metadata">

**Author:** ![Clinton\_Gormley](https://avatars.discourse-cdn.com/v4/letter/c/50afbb/32.png) [@Clinton\_Gormley](https://discuss.elastic.co/u/Clinton_Gormley)\
**Post date:** [February 19, 2010, 3:48pm UTC](https://discuss.elastic.co/t/formal-spec-for-query-dsl/2820/1 "2010-02-19T15:48:40Z")

</div>

Hiya

I'm trying to formalise the spec for the Query DSL used by  
ElasticSearch, both for my own understanding, and for making the Perl  
API more aware. The current docs assume a working knowledge of  
Lucene, which I don't have, so I'm writing this email to have my  
assumptions checked.

Below I've broken down all possible values that a query can have.  
Please could you check through it and make sure I'm not missing  
anything.

## Notes:

1. I've assumed that the various Filters are essentially the same as  
the related Query, but without a "boost", and, where appropriate,  
accepting other FILTER\_CLAUSEs instead of other QUERY\_CLAUSEs
2. I think that filteredQuery.filter should accept an array of filters  
as well (as bool.must does)
3. Am I right in saying that /\_count and delete\_by\_query accept a  
QUERY\_CLAUSE?
4. This correct: "term"s are for pre-tokenised values, while  
"queryString" is for text/phrases that need to be parsed?
5. In queryString, what do "prefix field", "enablePositionIncrements"  
and "fuzzyPrefixLength" mean?

thanks

Clint

## QUERY DSL SPEC: (better read in fixed-width font)

curl -XGET 'http://$server/\_all/\_search -d '{ TOPLEVEL }'  
curl -XGET 'http://$server/\_all/$types/\_search -d '{ TOPLEVEL }'  
curl -XGET 'http://$server/$indices/\_search -d '{ TOPLEVEL }'  
curl -XGET 'http://$server/$indices/$types/\_search -d '{ TOPLEVEL }'

## TOPLEVEL:

{  
explain: BOOL,  
from: INT,  
size: INT,  
fields: ["field\_1", "field\_n"],  
query: { QUERY\_CLAUSE },  
facets: { FACETS\_CLAUSE },  
sort: { SORT\_CLAUSE }  
}

## QUERY\_CLAUSE:

{  
term: { TERM\_QUERY }  
| range: { RANGE\_QUERY }  
| prefix: { PREFIX\_QUERY }  
| wildcard: { WILDCARD\_QUERY }  
| matchAll: { MATCH\_ALL\_QUERY }  
| queryString: { QUERY\_STRING\_QUERY }  
| bool: { BOOLEAN\_QUERY }  
| disMax: { DISMAX\_QUERY }  
| constantScore: { CONSTANT\_SCORE\_QUERY }  
| filteredQuery: { FILTERED\_QUERY },  
}

## FILTER\_CLAUSE:

{  
query: { QUERY\_CLAUSE },  
| term: { TERM\_FILTER },  
| range: { RANGE\_FILTER },  
| prefix: { PREFIX\_FILTER },  
| wildcard: { WILDCARD\_FILTER },  
| bool: { BOOLEAN\_FILTER },  
| constantScore: { CONSTANT\_SCORE\_QUERY }  
}

## FACETS\_CLAUSE:

{  
$facet\_name\_1: { FILTER\_CLAUSE },  
$facet\_name\_n: ...  
}

## SORT\_CLAUSE:

{  
$fieldname\_1 | "score" : {} | { reverse: BOOL },  
$fieldname\_n | "score" : ...  
}

## TERM\_FILTER:

{ $fieldname\_1: VALUE\_1, $fieldname\_n: VALUE\_n }

## TERM\_QUERY:

TERM\_FILTER  
| {  
$fieldname\_1: { value: VALUE\_1, boost: FLOAT\_1 },  
$fieldname\_n: ...  
}

## PREFIX\_FILTER:

{ $fieldname\_1: STRING\_1, $fieldname\_n: STRING\_n }

## PREFIX\_QUERY:

PREFIX\_FILTER  
| {  
$fieldname\_1: { prefix: STRING\_1, boost: FLOAT\_1 },  
$fieldname\_n: ...  
}

## WILDCARD\_FILTER:

{ $fieldname\_1: STRING\_1, $fieldname\_n: STRING\_n }

## WILDCARD\_QUERY:

WILDCARD\_FILTER  
| {  
$fieldname\_1: { wildcard: STRING\_1, boost: FLOAT\_1 },  
$fieldname\_n: ...  
}

## MATCH\_ALL\_QUERY:

{}  
| { boost: FLOAT }

## RANGE\_FILTER:

```
{ $fieldname: {
        from: INT | FLOAT | STRING,
        to: INT | FLOAT | STRING,
        includeLower: BOOL,
        includeUpper: BOOL,
}}

```

## RANGE\_QUERY:

```
{ $fieldname: {
        from: INT | FLOAT | STRING,
        to: INT | FLOAT | STRING,
        includeLower: BOOL
        includeUpper: BOOL
        boost: FLOAT
}}

```

## BOOLEAN\_FILTER:

```
{
    must: { FILTER_CLAUSE } | [{ FILTER_CLAUSE }, ...],
    should: { FILTER_CLAUSE } | [{ FILTER_CLAUSE }, ...],
    mustNot: { FILTER_CLAUSE } | [{ FILTER_CLAUSE }, ...],

    minimumNumberShouldMatch: INT
}

```

## BOOLEAN\_QUERY:

```
{
    must: { QUERY_CLAUSE} | [{ QUERY_CLAUSE }, ...],
    should: { QUERY_CLAUSE} | [{ QUERY_CLAUSE }, ...],
    mustNot: { QUERY_CLAUSE} | [{ QUERY_CLAUSE }, ...],

    boost: FLOAT,
    minimumNumberShouldMatch: INT
}

```

## DISMAX\_QUERY:

```
{
    queries: [{ QUERY_CLAUSE }, ...],
    tieBreakerMultiplier: FLOAT,
    boost: FLOAT
}

```

## CONSTANT\_SCORE\_QUERY:

```
{
    filter: { FILTER_CLAUSE }
    boost: FLOAT
}

```

## FILTERED\_QUERY:

```
{
    query: { QUERY_CLAUSE },
    filter: { FILTER_CLAUSE, ... }
}

```

## QUERY\_STRING\_QUERY:

{  
query: STRING,  
defaultField: $fieldname,  
defaultOperator: "AND" | "OR",  
analyzer: STRING,  
allowLeadingWildcard: BOOL,  
lowercaseExpandedTerms: BOOL,  
enablePositionIncrements: BOOL,  
fuzzyPrefixLength: BOOL,  
fuzzyMinSim: FLOAT,  
phraseSlop: INT,  
boost: FLOAT  
}

## ARGUMENT TYPES:

- BOOL: true | false
- INT: integer eg 5
- FLOAT: float eg 1.2
- STRING: text eg "foo"
- VALUE: BOOL | INT | FLOAT | STRING

---

<div class="post-metadata">

**Author:** ![kimchy](https://sea2.discourse-cdn.com/elastic/user_avatar/discuss.elastic.co/kimchy/32/44952_2.png) [@kimchy](https://discuss.elastic.co/u/kimchy)\
**Post date:** [February 19, 2010, 10:42pm UTC](https://discuss.elastic.co/t/formal-spec-for-query-dsl/2820/2 "2010-02-19T22:42:01Z")

</div>

Hi,

Answers below:

On Fri, Feb 19, 2010 at 5:48 PM, Clinton [clinton@iannounce.co.uk](mailto:clinton@iannounce.co.uk) wrote:

> Hiya
> 
> I'm trying to formalise the spec for the Query DSL used by  
> Elasticsearch, both for my own understanding, and for making the Perl  
> API more aware. The current docs assume a working knowledge of  
> Lucene, which I don't have, so I'm writing this email to have my  
> assumptions checked.
> 
> Below I've broken down all possible values that a query can have.  
> Please could you check through it and make sure I'm not missing  
> anything.
> 
> ## Notes:
> 
> 1. I've assumed that the various Filters are essentially the same as  
> the related Query, but without a "boost", and, where appropriate,  
> accepting other FILTER\_CLAUSEs instead of other QUERY\_CLAUSEs

Yes, they are very similar.

> 1. I think that filteredQuery.filter should accept an array of filters  
> as well (as bool.must does)

But then how should the relationship between filters be treated? The idea is  
that if you want more than one filter, simply create a bool filter and add  
filters to it.

> 1. Am I right in saying that /\_count and delete\_by\_query accept a  
> QUERY\_CLAUSE?

Yes.

> 1. This correct: "term"s are for pre-tokenised values, while  
> "queryString" is for text/phrases that need to be parsed?

Term query will match on the tokens that have been produced by the tokenizer  
and indexed. A query string tokenizes the query string and creates token  
queries (among others) from it.

> 1. In queryString, what do "prefix field", "enablePositionIncrements"  
> and "fuzzyPrefixLength" mean?

Where did you see "prefix field"? "enablePositionIncrements" (or positions  
in general) relate to the position of the tokens. Its important because some  
analyzers / tokenizers can, for example, remove tokens (like the stop  
filter), and in such cases, maintaining positions is important for things  
that relate to them (like phrase query, ".... ... ").

> thanks
> 
> Clint
> 
> ## QUERY DSL SPEC: (better read in fixed-width font)

Also (which is like \_all), thats in master:  
curl -XGET 'http://$server/\_search -d '{ TOPLEVEL }'

curl -XGET 'http://$server/\_all/\_search -d '{ TOPLEVEL }'

> curl -XGET 'http://$server/\_all/$types/\_search -d '{ TOPLEVEL }'  
> curl -XGET 'http://$server/$indices/\_search -d '{ TOPLEVEL }'  
> curl -XGET 'http://$server/$indices/$types/\_search -d '{ TOPLEVEL }'
> 
> ## TOPLEVEL:
> 
> {  
> explain: BOOL,  
> from: INT,  
> size: INT,  
> fields: ["field\_1", "field\_n"],  
> query: { QUERY\_CLAUSE },  
> facets: { FACETS\_CLAUSE },  
> sort: { SORT\_CLAUSE }  
> }
> 
> ## QUERY\_CLAUSE:
> 
> {  
> term: { TERM\_QUERY }  
> | range: { RANGE\_QUERY }  
> | prefix: { PREFIX\_QUERY }  
> | wildcard: { WILDCARD\_QUERY }  
> | matchAll: { MATCH\_ALL\_QUERY }  
> | queryString: { QUERY\_STRING\_QUERY }  
> | bool: { BOOLEAN\_QUERY }  
> | disMax: { DISMAX\_QUERY }  
> | constantScore: { CONSTANT\_SCORE\_QUERY }  
> | filteredQuery: { FILTERED\_QUERY },  
> }
> 
> ## FILTER\_CLAUSE:
> 
> {  
> query: { QUERY\_CLAUSE },  
> | term: { TERM\_FILTER },  
> | range: { RANGE\_FILTER },  
> | prefix: { PREFIX\_FILTER },  
> | wildcard: { WILDCARD\_FILTER },  
> | bool: { BOOLEAN\_FILTER },  
> | constantScore: { CONSTANT\_SCORE\_QUERY }  
> }
> 
> ## FACETS\_CLAUSE:
> 
> {  
> $facet\_name\_1: { FILTER\_CLAUSE },  
> $facet\_name\_n: ...  
> }

Facets accept a QUERY\_CLAUSE not a FILTER\_CLAUSE.

> ## SORT\_CLAUSE:
> 
> {  
> $fieldname\_1 | "score" : {} | { reverse: BOOL },  
> $fieldname\_n | "score" : ...  
> }
> 
> ## TERM\_FILTER:
> 
> { $fieldname\_1: VALUE\_1, $fieldname\_n: VALUE\_n }

Term filter only accept one field and value. If you want to filter on  
several terms, use a bool filter to wrap several term filters.

> ## TERM\_QUERY:
> 
> TERM\_FILTER  
> | {  
> $fieldname\_1: { value: VALUE\_1, boost: FLOAT\_1 },  
> $fieldname\_n: ...  
> }

Same as Term filter, only one field and value. Why do you have term filter  
there?

> ## PREFIX\_FILTER:
> 
> { $fieldname\_1: STRING\_1, $fieldname\_n: STRING\_n }

Just one field and value allowed.

> ## PREFIX\_QUERY:
> 
> PREFIX\_FILTER  
> | {  
> $fieldname\_1: { prefix: STRING\_1, boost: FLOAT\_1 },  
> $fieldname\_n: ...  
> }

Same as prefix filter, just one field and value allowed. Why do you have  
prefix filter there?

> ## WILDCARD\_FILTER:
> 
> { $fieldname\_1: STRING\_1, $fieldname\_n: STRING\_n }

Just one field name and value allowed.

> ## WILDCARD\_QUERY:
> 
> WILDCARD\_FILTER  
> | {  
> $fieldname\_1: { wildcard: STRING\_1, boost: FLOAT\_1 },  
> $fieldname\_n: ...  
> }

Just one field name and value allowed.

> ## MATCH\_ALL\_QUERY:
> 
> {}  
> | { boost: FLOAT }
> 
> ## RANGE\_FILTER:
> 
> { $fieldname: {  
> from: INT | FLOAT | STRING,  
> to: INT | FLOAT | STRING,  
> includeLower: BOOL,  
> includeUpper: BOOL,  
> }}
> 
> ## RANGE\_QUERY:
> 
> { $fieldname: {  
> from: INT | FLOAT | STRING,  
> to: INT | FLOAT | STRING,  
> includeLower: BOOL  
> includeUpper: BOOL  
> boost: FLOAT  
> }}
> 
> ## BOOLEAN\_FILTER:
> 
> {  
> must: { FILTER\_CLAUSE } | [{ FILTER\_CLAUSE }, ...],  
> should: { FILTER\_CLAUSE } | [{ FILTER\_CLAUSE }, ...],  
> mustNot: { FILTER\_CLAUSE } | [{ FILTER\_CLAUSE }, ...],
> 
> ```
> minimumNumberShouldMatch: INT
> 
> ```
> 
> }
> 
> ## BOOLEAN\_QUERY:
> 
> {  
> must: { QUERY\_CLAUSE} | [{ QUERY\_CLAUSE }, ...],  
> should: { QUERY\_CLAUSE} | [{ QUERY\_CLAUSE }, ...],  
> mustNot: { QUERY\_CLAUSE} | [{ QUERY\_CLAUSE }, ...],
> 
> ```
> boost: FLOAT,
> minimumNumberShouldMatch: INT
> 
> ```
> 
> }
> 
> ## DISMAX\_QUERY:
> 
> {  
> queries: [{ QUERY\_CLAUSE }, ...],  
> tieBreakerMultiplier: FLOAT,  
> boost: FLOAT  
> }
> 
> ## CONSTANT\_SCORE\_QUERY:
> 
> {  
> filter: { FILTER\_CLAUSE }  
> boost: FLOAT  
> }
> 
> ## FILTERED\_QUERY:
> 
> {  
> query: { QUERY\_CLAUSE },  
> filter: { FILTER\_CLAUSE, ... }  
> }
> 
> ## QUERY\_STRING\_QUERY:
> 
> {  
> query: STRING,  
> defaultField: $fieldname,  
> defaultOperator: "AND" | "OR",  
> analyzer: STRING,  
> allowLeadingWildcard: BOOL,  
> lowercaseExpandedTerms: BOOL,  
> enablePositionIncrements: BOOL,  
> fuzzyPrefixLength: BOOL,  
> fuzzyMinSim: FLOAT,  
> phraseSlop: INT,  
> boost: FLOAT  
> }
> 
> ## ARGUMENT TYPES:
> 
> - BOOL: true | false
> - INT: integer eg 5
> - FLOAT: float eg 1.2
> - STRING: text eg "foo"
> - VALUE: BOOL | INT | FLOAT | STRING

---

<div class="post-metadata">

**Author:** ![Clinton\_Gormley](https://avatars.discourse-cdn.com/v4/letter/c/50afbb/32.png) [@Clinton\_Gormley](https://discuss.elastic.co/u/Clinton_Gormley)\
**Post date:** [February 20, 2010, 4:22pm UTC](https://discuss.elastic.co/t/formal-spec-for-query-dsl/2820/3 "2010-02-20T16:22:21Z")

</div>

Hiya

> ```
> 2) I think that filteredQuery.filter should accept an array of
> filters
> as well (as bool.must does)
> 
> ```
> 
> But then how should the relationship between filters be treated? The  
> idea is that if you want more than one filter, simply create a bool  
> filter and add filters to it.

Ah ok - gotcha

> ```
> 5) In queryString, what do "prefix field",
> "enablePositionIncrements"
> and "fuzzyPrefixLength" mean?
> 
> ```
> 
> Where did you see "prefix field"?

In the docs on  
[http://www.elasticsearch.com/docs/elasticsearch/rest\_api/query\_dsl/](http://www.elasticsearch.com/docs/elasticsearch/rest_api/query_dsl/)

you have:

```
defaultField: The default field for query terms if no prefix field
               is specified. 

```

> 

Based on your comments, I've update my DSL spec. Would it be worth  
putting this on the website?

## QUERY DSL SPEC: (better read in fixed-width font)

curl -XGET 'http://$server/\_search -d '{ TOPLEVEL }'  
curl -XGET 'http://$server/\_all/\_search -d '{ TOPLEVEL }'  
curl -XGET 'http://$server/\_all/$types/\_search -d '{ TOPLEVEL }'  
curl -XGET 'http://$server/$indices/\_search -d '{ TOPLEVEL }'  
curl -XGET 'http://$server/$indices/$types/\_search -d '{ TOPLEVEL }'

## TOPLEVEL:

{  
explain: BOOL,  
from: INT,  
size: INT,  
fields: ["field\_1", "field\_n"],  
query: { QUERY\_CLAUSE },  
facets: { FACETS\_CLAUSE },  
sort: { SORT\_CLAUSE }  
}

## QUERY\_CLAUSE:

{  
term: { TERM\_QUERY }  
| range: { RANGE\_QUERY }  
| prefix: { PREFIX\_QUERY }  
| wildcard: { WILDCARD\_QUERY }  
| matchAll: { MATCH\_ALL\_QUERY }  
| queryString: { QUERY\_STRING\_QUERY }  
| bool: { BOOLEAN\_QUERY }  
| disMax: { DISMAX\_QUERY }  
| constantScore: { CONSTANT\_SCORE\_QUERY }  
| filteredQuery: { FILTERED\_QUERY },  
}

## FILTER\_CLAUSE:

{  
query: { QUERY\_CLAUSE },  
| term: { TERM\_FILTER },  
| range: { RANGE\_FILTER },  
| prefix: { PREFIX\_FILTER },  
| wildcard: { WILDCARD\_FILTER },  
| bool: { BOOLEAN\_FILTER },  
| constantScore: { CONSTANT\_SCORE\_QUERY }  
}

## FACETS\_CLAUSE:

{  
$facet\_name\_1: { QUERY\_CLAUSE },  
$facet\_name\_n: ...  
}

## SORT\_CLAUSE:

[  
$fieldname\_1 | "score  
| { $fieldname\_1 : { reverse: BOOL }},  
...  
]

## TERM\_FILTER:

{ $fieldname: VALUE\_1 }

## TERM\_QUERY:

{ $fieldname: VALUE\_1 }  
| { $fieldname: { value: VALUE, boost: FLOAT } }

## PREFIX\_FILTER:

{ $fieldname: STRING}

## PREFIX\_QUERY:

{ $fieldname: STRING}  
| { $fieldname: { prefix: STRING\_1, boost: FLOAT } }

## WILDCARD\_FILTER:

{ $fieldname: STRING }

## WILDCARD\_QUERY:

{ $fieldname: STRING }  
| { $fieldname: { wildcard: STRING, boost: FLOAT } }

## MATCH\_ALL\_QUERY:

{}  
| { boost: FLOAT }

## RANGE\_FILTER:

```
{ $fieldname: {
        from: INT | FLOAT | STRING | DATETIME,
        to: INT | FLOAT | STRINGï»¿ | DATETIME,
        includeLower: BOOL,
        includeUpper: BOOL,
}}

```

## RANGE\_QUERY:

```
{ $fieldname: {
        from: INT | FLOAT | STRINGï»¿ | DATETIME,
        to: INT | FLOAT | STRINGï»¿ | DATETIME,
        includeLower: BOOL
        includeUpper: BOOL
        boost: FLOAT        
}}

```

## BOOLEAN\_FILTER:

```
{
    must: { FILTER_CLAUSE } | [{ FILTER_CLAUSE }, ...],
    should: { FILTER_CLAUSE } | [{ FILTER_CLAUSE }, ...],
    mustNot: { FILTER_CLAUSE } | [{ FILTER_CLAUSE }, ...],
    
    minimumNumberShouldMatch: INT
}

```

## BOOLEAN\_QUERY:

```
{
    must: { QUERY_CLAUSE} | [{ QUERY_CLAUSE }, ...],
    should: { QUERY_CLAUSE} | [{ QUERY_CLAUSE }, ...],
    mustNot: { QUERY_CLAUSE} | [{ QUERY_CLAUSE }, ...],
    
    boost: FLOAT,
    minimumNumberShouldMatch: INT
}

```

## DISMAX\_QUERY:

```
{
    queries: [{ QUERY_CLAUSE }, ...],
    tieBreakerMultiplier: FLOAT,
    boost: FLOAT
}

```

## CONSTANT\_SCORE\_QUERY:

```
{
    filter: { FILTER_CLAUSE }
    boost: FLOAT
}

```

## FILTERED\_QUERY:

```
{
    query: { QUERY_CLAUSE },
    filter: { FILTER_CLAUSE, ... }
}

```

## QUERY\_STRING\_QUERY:

{  
query: STRING,  
defaultField: $fieldname,  
defaultOperator: "AND" | "OR",  
analyzer: STRING,  
allowLeadingWildcard: BOOL,  
lowercaseExpandedTerms: BOOL,  
enablePositionIncrements: BOOL,  
fuzzyPrefixLength: BOOL,  
fuzzyMinSim: FLOAT,  
phraseSlop: INT,  
boost: FLOAT  
}

## ARGUMENT TYPES:

- BOOL: true | false
- INT: integer eg 5
- FLOAT: float eg 1.2
- STRING: text eg "foo"
- DATETIME: dates and times  
eg ï»¿"ï»¿2010-02-31T13:30:45", "2010-02-31", ï»¿"13:30:45"
- VALUE: BOOL | INT | FLOAT | STRING | DATETIME

thanks

clint

--  
Web Announcements Limited is a company registered in England and Wales,  
with company number 05608868, with registered address at 10 Arvon Road,  
London, N5 1PR.

---

<div class="post-metadata">

**Author:** ![kimchy](https://sea2.discourse-cdn.com/elastic/user_avatar/discuss.elastic.co/kimchy/32/44952_2.png) [@kimchy](https://discuss.elastic.co/u/kimchy)\
**Post date:** [February 20, 2010, 5:19pm UTC](https://discuss.elastic.co/t/formal-spec-for-query-dsl/2820/4 "2010-02-20T17:19:04Z")

</div>

Regarding the field, what I meant by a prefix field is that you can execute  
a query string with "fieldA:valueA", in this case, you have a prefix field  
for valueA, but, you can also execute a query with just "valueA", in this  
case, it will run against the defaultField.

Regarding the spec, can you send it to me as a txt file and I will add it to  
the site.

Thanks for the effort!  
Shay

On Sat, Feb 20, 2010 at 6:22 PM, Clinton Gormley [clinton@iannounce.co.uk](mailto:clinton@iannounce.co.uk)wrote:

> Hiya
> 
> > ```
> > 2) I think that filteredQuery.filter should accept an array of
> > filters
> > as well (as bool.must does)
> > 
> > ```
> > 
> > But then how should the relationship between filters be treated? The  
> > idea is that if you want more than one filter, simply create a bool  
> > filter and add filters to it.
> 
> Ah ok - gotcha
> 
> > ```
> > 5) In queryString, what do "prefix field",
> > "enablePositionIncrements"
> > and "fuzzyPrefixLength" mean?
> > 
> > ```
> > 
> > Where did you see "prefix field"?
> 
> In the docs on  
> [http://www.elasticsearch.com/docs/elasticsearch/rest\_api/query\_dsl/](http://www.elasticsearch.com/docs/elasticsearch/rest_api/query_dsl/)
> 
> you have:
> 
> defaultField: The default field for query terms if no prefix field  
> is specified.
> 
> > 
> 
> Based on your comments, I've update my DSL spec. Would it be worth  
> putting this on the website?
> 
> ## QUERY DSL SPEC: (better read in fixed-width font)
> 
> curl -XGET 'http://$server/\_search -d '{ TOPLEVEL }'  
> curl -XGET 'http://$server/\_all/\_search -d '{ TOPLEVEL }'  
> curl -XGET 'http://$server/\_all/$types/\_search -d '{ TOPLEVEL }'  
> curl -XGET 'http://$server/$indices/\_search -d '{ TOPLEVEL }'  
> curl -XGET 'http://$server/$indices/$types/\_search -d '{ TOPLEVEL }'
> 
> ## TOPLEVEL:
> 
> {  
> explain: BOOL,  
> from: INT,  
> size: INT,  
> fields: ["field\_1", "field\_n"],  
> query: { QUERY\_CLAUSE },  
> facets: { FACETS\_CLAUSE },  
> sort: { SORT\_CLAUSE }  
> }
> 
> ## QUERY\_CLAUSE:
> 
> {  
> term: { TERM\_QUERY }  
> | range: { RANGE\_QUERY }  
> | prefix: { PREFIX\_QUERY }  
> | wildcard: { WILDCARD\_QUERY }  
> | matchAll: { MATCH\_ALL\_QUERY }  
> | queryString: { QUERY\_STRING\_QUERY }  
> | bool: { BOOLEAN\_QUERY }  
> | disMax: { DISMAX\_QUERY }  
> | constantScore: { CONSTANT\_SCORE\_QUERY }  
> | filteredQuery: { FILTERED\_QUERY },  
> }
> 
> ## FILTER\_CLAUSE:
> 
> {  
> query: { QUERY\_CLAUSE },  
> | term: { TERM\_FILTER },  
> | range: { RANGE\_FILTER },  
> | prefix: { PREFIX\_FILTER },  
> | wildcard: { WILDCARD\_FILTER },  
> | bool: { BOOLEAN\_FILTER },  
> | constantScore: { CONSTANT\_SCORE\_QUERY }  
> }
> 
> ## FACETS\_CLAUSE:
> 
> {  
> $facet\_name\_1: { QUERY\_CLAUSE },  
> $facet\_name\_n: ...  
> }
> 
> ## SORT\_CLAUSE:
> 
> [  
> $fieldname\_1 | "score  
> | { $fieldname\_1 : { reverse: BOOL }},  
> ...  
> ]
> 
> ## TERM\_FILTER:
> 
> { $fieldname: VALUE\_1 }
> 
> ## TERM\_QUERY:
> 
> { $fieldname: VALUE\_1 }  
> | { $fieldname: { value: VALUE, boost: FLOAT } }
> 
> ## PREFIX\_FILTER:
> 
> { $fieldname: STRING}
> 
> ## PREFIX\_QUERY:
> 
> { $fieldname: STRING}  
> | { $fieldname: { prefix: STRING\_1, boost: FLOAT } }
> 
> ## WILDCARD\_FILTER:
> 
> { $fieldname: STRING }
> 
> ## WILDCARD\_QUERY:
> 
> { $fieldname: STRING }  
> | { $fieldname: { wildcard: STRING, boost: FLOAT } }
> 
> ## MATCH\_ALL\_QUERY:
> 
> {}  
> | { boost: FLOAT }
> 
> ## RANGE\_FILTER:
> 
> { $fieldname: {  
> from: INT | FLOAT | STRING | DATETIME,  
> to: INT | FLOAT | STRING﻿ | DATETIME,  
> includeLower: BOOL,  
> includeUpper: BOOL,  
> }}
> 
> ## RANGE\_QUERY:
> 
> { $fieldname: {  
> from: INT | FLOAT | STRING﻿ | DATETIME,  
> to: INT | FLOAT | STRING﻿ | DATETIME,  
> includeLower: BOOL  
> includeUpper: BOOL  
> boost: FLOAT  
> }}
> 
> ## BOOLEAN\_FILTER:
> 
> {  
> must: { FILTER\_CLAUSE } | [{ FILTER\_CLAUSE }, ...],  
> should: { FILTER\_CLAUSE } | [{ FILTER\_CLAUSE }, ...],  
> mustNot: { FILTER\_CLAUSE } | [{ FILTER\_CLAUSE }, ...],
> 
> ```
> minimumNumberShouldMatch: INT
> 
> ```
> 
> }
> 
> ## BOOLEAN\_QUERY:
> 
> {  
> must: { QUERY\_CLAUSE} | [{ QUERY\_CLAUSE }, ...],  
> should: { QUERY\_CLAUSE} | [{ QUERY\_CLAUSE }, ...],  
> mustNot: { QUERY\_CLAUSE} | [{ QUERY\_CLAUSE }, ...],
> 
> ```
> boost: FLOAT,
> minimumNumberShouldMatch: INT
> 
> ```
> 
> }
> 
> ## DISMAX\_QUERY:
> 
> {  
> queries: [{ QUERY\_CLAUSE }, ...],  
> tieBreakerMultiplier: FLOAT,  
> boost: FLOAT  
> }
> 
> ## CONSTANT\_SCORE\_QUERY:
> 
> {  
> filter: { FILTER\_CLAUSE }  
> boost: FLOAT  
> }
> 
> ## FILTERED\_QUERY:
> 
> {  
> query: { QUERY\_CLAUSE },  
> filter: { FILTER\_CLAUSE, ... }  
> }
> 
> ## QUERY\_STRING\_QUERY:
> 
> {  
> query: STRING,  
> defaultField: $fieldname,  
> defaultOperator: "AND" | "OR",  
> analyzer: STRING,  
> allowLeadingWildcard: BOOL,  
> lowercaseExpandedTerms: BOOL,  
> enablePositionIncrements: BOOL,  
> fuzzyPrefixLength: BOOL,  
> fuzzyMinSim: FLOAT,  
> phraseSlop: INT,  
> boost: FLOAT  
> }
> 
> ## ARGUMENT TYPES:
> 
> - BOOL: true | false
> - INT: integer eg 5
> - FLOAT: float eg 1.2
> - STRING: text eg "foo"
> - DATETIME: dates and times  
> eg ﻿"﻿2010-02-31T13:30:45", "2010-02-31", ﻿"13:30:45"
> - VALUE: BOOL | INT | FLOAT | STRING | DATETIME
> 
> thanks
> 
> clint
> 
> --  
> Web Announcements Limited is a company registered in England and Wales,  
> with company number 05608868, with registered address at 10 Arvon Road,  
> London, N5 1PR.

---

<div class="post-metadata">

**Author:** ![Frederic\_Laurent](https://avatars.discourse-cdn.com/v4/letter/f/c67d28/32.png) [@Frederic\_Laurent](https://discuss.elastic.co/u/Frederic_Laurent)\
**Post date:** [August 7, 2015, 8:46am UTC](https://discuss.elastic.co/t/formal-spec-for-query-dsl/2820/5 "2015-08-07T08:46:31Z")

</div>

Hello Shay,  
Did you finally publish the formal spec off the DSL on the elastic.co website ?  
If so, can you give a link ?

Thanks

---

<div class="post-metadata">

**Author:** ![system](https://us1.discourse-cdn.com/elastic/original/3X/1/a/1ac57faf039f6b580b3f104ef42a2a89e41014de.png) [@system](https://discuss.elastic.co/u/system)\
**Post date:** [July 5, 2017, 11:56pm UTC](https://discuss.elastic.co/t/formal-spec-for-query-dsl/2820/6 "2017-07-05T23:56:53Z")

</div>


