diff --git a/CHANGELOG.md b/CHANGELOG.md
index eba6f0acc6a2fde88f60e098e6318e245d467b7e..497a4d5c384ec5b8180918f19e56b8262d4f2187 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -1,10 +1,14 @@
 # CHANGELOG
 v5.0.0 (2017-x)
 ---
-- **[BC break]** Removed deprecated aggregation classes.
-- **[BC break]** Removed deprecated query classes.
-- **[BC break]** `Search::getQueryParams()` changed to `Search::getUriParams()`.
-- **[BC break]** `FilterEndpoint` was removed due deprecated filters.
+- **Namespace for some queries were changed**. Queries were consolidated to a domain like Elasticsearch does.  All queries were grouped to `Compound`, `FullText`, `Geo`, `Joining`, `Span`, `Specialized` and `TermLevel`.
+- PHP version support changed to >=5.6
+- Added `elasticsearch\elasticsearch` to required dependency list in the composer.json.
+- Deprecated aggregations removed. Check if the namespace is correct. All aggregations grouped to `Bucketing`, `Metric` and `Pipeline` namespaces.
+- `Search::getQueryParams()` changed to `Search::getUriParams()`. All setter's for request URI parameters removed in favor of `uriParams` container. You can add URI parameters by `addUriParam`, and this function also has validation.
+- `Search::setFields()` and `Search::getFields()` were changed to `Search::setStoredFields()` and `Search::getStoredFields()`.
+- `FilterEndpoint` was removed due to deprecated filters in elasticsearch.
+- Added missing scroll param to URL params (#202)
 
 v2.2.1 (2017-01-26)
 ---
diff --git a/README.md b/README.md
index a1e2c9ccdb07b8a133d06b5ffd5181846b9c8e37..553756ab8ae83169d3b79b0d0a02df0a5a4367b2 100644
--- a/README.md
+++ b/README.md
@@ -15,14 +15,15 @@ is the preffered and recommended way to ask ONGR support questions.
 
 | Elasticsearch version | ElasticsearchDSL version    |
 | --------------------- | --------------------------- |
-| >= 5.0                | >= 5.0                       |
-| >= 2.0, < 5.0         | >= 2.0                       |
+| >= 5.0                | >= 5.0                      |
+| >= 2.0, < 5.0         | >= 2.0, < 5.0               |
 | >= 1.0, < 2.0         | 1.x                         |
-| <= 0.90.x             | not supported               |
+| <= 0.90.x             | 0.x                         |
 
 ## Documentation
 
-[The online documentation of the bundle is here](docs/index.md)
+The latest library online documentation of the bundle [is here](http://docs.ongr.io/ElasticsearchDSL). If you need 2.x 
+docs you can find it in [the github branch here](https://github.com/ongr-io/ElasticsearchDSL/tree/2.x/docs).
 
 ## Try it!
 
@@ -34,24 +35,27 @@ Install library with [composer](https://getcomposer.org):
 $ composer require ongr/elasticsearch-dsl
 ```
 
+> [elasticsearch-php](https://github.com/elastic/elasticsearch-php) client is defined in the composer requirements, no need to install it.
+
 ### Search
 
 Elasticsearch DSL was extracted from [Elasticsearch Bundle](https://github.com/ongr-io/ElasticsearchBundle) to provide standalone query dsl for [elasticsearch-php](https://github.com/elastic/elasticsearch-php). Examples how to use it together with [Elasticsearch Bundle](https://github.com/ongr-io/ElasticsearchBundle) can be found in the [Elasticsearch Bundle docs](https://github.com/ongr-io/ElasticsearchBundle/blob/master/Resources/doc/search.md).
 
 If you dont want to use Symfony or Elasticsearch bundle, no worries, you can use it in any project together with [elasticsearch-php](https://github.com/elastic/elasticsearch-php). Here's the example:
 
-Install `elasticsearch-php`:
+If you are using Symfony there is also the [ElasticsearchBundle](https://github.com/ongr-io/ElasticsearchBundle)
+which provides full integration with Elasticsearch DSL. 
 
-```bash
-$ composer require elasticsearch/elasticsearch
-```
+The library is standalone and is not coupled with any framework. You can use it in any PHP project, the only
+requirement is composer.  Here's the example:
 
 Create search:
 
 ```php
  <?php
-  require 'vendor/autoload.php';
-  $client = ClientBuilder::create()->build();
+  require 'vendor/autoload.php'; //Composer autoload
+  
+  $client = ClientBuilder::create()->build(); //elasticsearch-php client
   
   $matchAll = new ONGR\ElasticsearchDSL\Query\MatchAllQuery();
   
diff --git a/docs/HowTo/HowToSearch.md b/docs/HowTo/HowToSearch.md
index 3541c2b89c117da9e7dacc4bab7b34c260f27d38..25b6b8748b2e8ed129af90304e9dc8e31c8554c2 100644
--- a/docs/HowTo/HowToSearch.md
+++ b/docs/HowTo/HowToSearch.md
@@ -10,7 +10,7 @@ $search = new Search();
 
 > We won't include namespaces in any examples. Don't worry all class's names are unique, so any IDE editor should autocomplete and include it for you ;).
 
-So, when we have a `Search` object we can start add something to it. Usually you will add `Query`, `Filter` and `Aggregation`.
+So, when we have a `Search` object we can start adding something to it. Usually you will add `Query` and `Aggregation`.
 
 > More info how create [queries](../Query/index.md) and [aggregations](../Aggregation/index.md) objects.
 
@@ -43,32 +43,40 @@ At the end it will form this query:
 
 ### Form a Filter
 
-Since Elasticsearch 2.0 all filters were replaced by queries. Queries acts like
-filters when you use them in filter context.
-
-To add a filter is the same way like a query. First, lets create some `Filter` object.
-
+Since Elasticsearch 5.0 the support for top level filters was dropped. The same functionality
+is now supported via `BoolQuery`. Adding a filter to the bool query is done like so:
+ 
 ```php
-$matchAllQuery = new MatchAllQuery();
-```
-
-And simply add to the `Search`:
+$search = new Search();
+$boolQuery = new BoolQuery();
+$boolQuery->add(new MatchAllQuery());
+$geoQuery = new TermQuery('field', 'value');
+$boolQuery->add($geoQuery, BoolQuery::FILTER);
+$search->addQuery($boolQuery);
 
-```php
-$search->addFilter($matchAllQuery);
+$search->toArray();
 ```
 
-Unlike `Query`, when we add a `Filter` with our DSL library it will add a query and all necessary stuff for you. So when we add one filter we will get this query:
+This will result in
 
-```JSON
+```
 {
-  "query": {
-      "bool": {
-          "filter": {
-              "match_all": {}
-          }
-      }
-  }
+    "query": {
+        "bool": {
+            "must": [
+                {
+                    "match_all": {}
+                }
+            ],
+            "filter": [
+                {
+                    "term": {
+                        "field": "value"
+                    }
+                }
+            ]
+        }
+    }
 }
 ```
 
@@ -113,63 +121,17 @@ The query will look like:
 ```
 > More info how to form bool queries find in [Bool Query](../Query/Bool.md) chapter.
 
-The same way it works with a `Filter`. Take a look at this example:
-
-```php
-$search = new Search();
-$termFilter = new TermQuery('name', 'ongr');
-$missingFilter = new MissingQuery('disabled');
-$existsFilter = new ExistsQuery('tag');
-$search->addFilter($termFilter);
-$search->addFilter($missingFilter);
-$search->addFilter($existsFilter, BoolQuery::MUST_NOT);
-```
-
-Elasticsearch DSL will form this query:
-
-```JSON
-{
-  "query": {
-    "bool": {
-        "filter": {
-            "bool": {
-                "must": [
-                    {
-                        "term": {
-                            "name": "ongr"
-                        }
-                    },
-                    {
-                        "missing": {
-                            "field": "disabled"
-                        }
-                    }
-                ],
-                "must_not": [
-                    {
-                        "exists": {
-                            "field": "tag"
-                        }
-                    }
-                ]
-            }
-        }
-    }
-  }
-}
-```
-
 ### Modify queries
 
 
 
 
 ### Sent request to the elasticsearch
-And finaly we can pass it to `elasticsearch-php` client. To generate an array for the client we call `toArray()` function.
+And finally we can pass it to `elasticsearch-php` client. To generate an array for the client we call `toArray()` function.
 
 ```php
 //from elasticsearch/elasticsearch package
-$client = new Elasticsearch\Client();
+$client = ClientBuilder::create()->build();
 
 $searchParams = [
   'index' => 'people',
@@ -180,4 +142,4 @@ $searchParams = [
 $docs = $client->search($searchParams);
 ```
 
-> This example is for elasticsearch/elasticsearch ~1.0 version.
+> This example is for elasticsearch/elasticsearch ~5.0 version.
diff --git a/docs/Query/Bool.md b/docs/Query/Compound/Bool.md
similarity index 100%
rename from docs/Query/Bool.md
rename to docs/Query/Compound/Bool.md
diff --git a/docs/Query/Boosting.md b/docs/Query/Compound/Boosting.md
similarity index 100%
rename from docs/Query/Boosting.md
rename to docs/Query/Compound/Boosting.md
diff --git a/docs/Query/ConstantScore.md b/docs/Query/Compound/ConstantScore.md
similarity index 100%
rename from docs/Query/ConstantScore.md
rename to docs/Query/Compound/ConstantScore.md
diff --git a/docs/Query/DisMax.md b/docs/Query/Compound/DisMax.md
similarity index 100%
rename from docs/Query/DisMax.md
rename to docs/Query/Compound/DisMax.md
diff --git a/docs/Query/FunctionScore.md b/docs/Query/Compound/FunctionScore.md
similarity index 100%
rename from docs/Query/FunctionScore.md
rename to docs/Query/Compound/FunctionScore.md
diff --git a/docs/Query/Indices.md b/docs/Query/Compound/Indices.md
similarity index 100%
rename from docs/Query/Indices.md
rename to docs/Query/Compound/Indices.md
diff --git a/docs/Query/CommonTerms.md b/docs/Query/FullText/CommonTerms.md
similarity index 100%
rename from docs/Query/CommonTerms.md
rename to docs/Query/FullText/CommonTerms.md
diff --git a/docs/Query/Match.md b/docs/Query/FullText/Match.md
similarity index 100%
rename from docs/Query/Match.md
rename to docs/Query/FullText/Match.md
diff --git a/docs/Query/FullText/MatchPhrase.md b/docs/Query/FullText/MatchPhrase.md
new file mode 100644
index 0000000000000000000000000000000000000000..b39b0c362c9f1111a40ad6b50d26547509d9a05b
--- /dev/null
+++ b/docs/Query/FullText/MatchPhrase.md
@@ -0,0 +1,34 @@
+# MatchPhrase Query
+
+> More info about match phrase query is in the [official elasticsearch docs][1]
+
+The match_phrase query analyzes the text and creates a phrase query out of the analyzed text. For example:
+
+## Simple example
+
+```JSON
+{
+    "query": {
+        "match_phrase" : {
+            "message" : {
+                "query" : "this is a test",
+                "analyzer" : "my_analyzer"
+            }
+        }
+    }
+}
+```
+
+In DSL:
+
+```php
+$query = new MatchPhraseQuery('message', 'this is a test');
+$query->addParameter('analyzer', 'my_analyzer');
+
+$search = new Search();
+$search->addQuery($query);
+
+$queryArray = $search->toArray();
+```
+
+[1]: https://www.elastic.co/guide/en/elasticsearch/reference/current/query-dsl-match-query-phrase.html
diff --git a/docs/Query/FullText/MatchPhrasePrefix.md b/docs/Query/FullText/MatchPhrasePrefix.md
new file mode 100644
index 0000000000000000000000000000000000000000..e690ad8f4e29fd3edfd33466133d98a8195b2c49
--- /dev/null
+++ b/docs/Query/FullText/MatchPhrasePrefix.md
@@ -0,0 +1,34 @@
+# Match Phrase Prefix Query
+
+> More info about match phrase prefix query is in the [official elasticsearch docs][1]
+
+The `match_phrase_prefix` is the same as `match_phrase`, except that it allows for prefix matches on the last term in the text. For example
+
+## Simple example
+
+```JSON
+{
+    "query": {
+        "match_phrase_prefix" : {
+            "message" : {
+                "query" : "quick brown f",
+                "max_expansions" : 10
+            }
+        }
+    }
+}
+```
+
+In DSL:
+
+```php
+$query = new MatchPhrasePrefixQuery('message', 'quick brown f');
+$query->addParameter('max_expansions', 10);
+
+$search = new Search();
+$search->addQuery($query);
+
+$queryArray = $search->toArray();
+```
+
+[1]: https://www.elastic.co/guide/en/elasticsearch/reference/current/query-dsl-match-query-phrase-prefix.html
diff --git a/docs/Query/MultiMatch.md b/docs/Query/FullText/MultiMatch.md
similarity index 100%
rename from docs/Query/MultiMatch.md
rename to docs/Query/FullText/MultiMatch.md
diff --git a/docs/Query/QueryString.md b/docs/Query/FullText/QueryString.md
similarity index 100%
rename from docs/Query/QueryString.md
rename to docs/Query/FullText/QueryString.md
diff --git a/docs/Query/SimpleQueryString.md b/docs/Query/FullText/SimpleQueryString.md
similarity index 100%
rename from docs/Query/SimpleQueryString.md
rename to docs/Query/FullText/SimpleQueryString.md
diff --git a/docs/Query/Geo/GeoBoundingBox.md b/docs/Query/Geo/GeoBoundingBox.md
new file mode 100644
index 0000000000000000000000000000000000000000..42658c03d4cef796df5ec68c7319c334716ec146
--- /dev/null
+++ b/docs/Query/Geo/GeoBoundingBox.md
@@ -0,0 +1,97 @@
+# Geo Bounding Box Query
+
+> More info about geo bounding box query is in the [official elasticsearch docs][1]
+
+A query allowing to filter hits based on a point location using a bounding box. Assuming the following indexed document:
+
+## Simple example
+
+```JSON
+{
+    "query": {
+        "bool" : {
+            "must" : {
+                "match_all" : {}
+            },
+            "filter" : {
+                "geo_bounding_box" : {
+                    "pin.location" : {
+                        "top_left" : {
+                            "lat" : 40.73,
+                            "lon" : -74.1
+                        },
+                        "bottom_right" : {
+                            "lat" : 40.01,
+                            "lon" : -71.12
+                        }
+                    }
+                }
+            }
+        }
+    }
+}
+```
+
+In DSL:
+
+```php
+$search = new Search();
+$location = [
+    ['lat' => 40.73, 'lon' => -74.1],
+    [ 'lat' => 40.01, 'lon' => -71.12],
+];
+$boolQuery = new BoolQuery();
+$boolQuery->add(new MatchAllQuery());
+$geoQuery = new GeoBoundingBoxQuery('pin.location', $location);
+$boolQuery->add($geoQuery, BoolQuery::FILTER);
+$search->addQuery($boolQuery);
+
+$queryArray = $search->toArray();
+```
+
+> This query accepts an array with either 2 or 4 elements as its second parameter,
+failing to meet this criteria will result in an error!
+
+Alternatively the vertices of the bounding box can be set separately:
+
+```json
+
+{
+    "query": {
+        "bool" : {
+            "must" : {
+                "match_all" : {}
+            },
+            "filter" : {
+                "geo_bounding_box" : {
+                    "pin.location" : {
+                        "top" : 40.73,
+                        "left" : -74.1,
+                        "bottom" : 40.01,
+                        "right" : -71.12
+                    }
+                }
+            }
+        }
+    }
+}
+
+```
+
+Now via DSL:
+
+```php
+
+$search = new Search();
+$location = [40.73, -74.1, 40.01, -71.12];
+$boolQuery = new BoolQuery();
+$boolQuery->add(new MatchAllQuery());
+$geoQuery = new GeoBoundingBoxQuery('pin.location', $location);
+$boolQuery->add($geoQuery, BoolQuery::FILTER);
+$search->addQuery($boolQuery);
+
+$queryArray = $search->toArray();
+
+```
+
+[1]: https://www.elastic.co/guide/en/elasticsearch/reference/current/query-dsl-geo-bounding-box-query.html
diff --git a/docs/Query/Geo/GeoDistance.md b/docs/Query/Geo/GeoDistance.md
new file mode 100644
index 0000000000000000000000000000000000000000..58e9b9dad77089d2858191ee6f1f5bfa2d103c89
--- /dev/null
+++ b/docs/Query/Geo/GeoDistance.md
@@ -0,0 +1,81 @@
+# Geo Distance Query
+
+> More info about geo distance query is in the [official elasticsearch docs][1]
+
+Filters documents that include only hits that exists within a specific distance from a geo point:
+
+## Simple example
+
+```JSON
+{
+    "query": {
+        "bool" : {
+            "must" : {
+                "match_all" : {}
+            },
+            "filter" : {
+                "geo_distance" : {
+                    "distance" : "200km",
+                    "pin.location" : {
+                        "lat" : 40,
+                        "lon" : -70
+                    }
+                }
+            }
+        }
+    }
+}
+```
+
+In DSL:
+
+```php
+$search = new Search();
+$boolQuery = new BoolQuery();
+$boolQuery->add(new MatchAllQuery());
+$geoQuery = new GeoDistanceQuery('pin.location', '200km', ['lat' => 40, 'lon' => -70]);
+$boolQuery->add($geoQuery, BoolQuery::FILTER);
+$search->addQuery($boolQuery);
+
+$queryArray = $search->toArray();
+```
+
+Here, elasticsearch supports passing location in a variety of different formats, therefore
+the query permits that as well, however it is up to the user to ensure the validity of the 
+data passed to this parameter. Following is an example of a valid location being passed as 
+a string:
+
+```json
+
+{
+    "query": {
+        "bool" : {
+            "must" : {
+                "match_all" : {}
+            },
+            "filter" : {
+                "geo_distance" : {
+                    "distance" : "12km",
+                    "pin.location" : "drm3btev3e86"
+                }
+            }
+        }
+    }
+}
+
+```
+
+And now via DSL:
+
+```php
+$search = new Search();
+$boolQuery = new BoolQuery();
+$boolQuery->add(new MatchAllQuery());
+$geoQuery = new GeoDistanceQuery('pin.location', '200km', 'drm3btev3e86');
+$boolQuery->add($geoQuery, BoolQuery::FILTER);
+$search->addQuery($boolQuery);
+
+$queryArray = $search->toArray();
+```
+
+[1]: https://www.elastic.co/guide/en/elasticsearch/reference/current/query-dsl-geo-distance-query.html
diff --git a/docs/Query/Geo/GeoDistanceRange.md b/docs/Query/Geo/GeoDistanceRange.md
new file mode 100644
index 0000000000000000000000000000000000000000..f0c825cac94e0e8142c697e520a633cefa3c6f71
--- /dev/null
+++ b/docs/Query/Geo/GeoDistanceRange.md
@@ -0,0 +1,50 @@
+# Geo Distance Range Query
+
+> More info about geo distance range query is in the [official elasticsearch docs][1]
+
+> This query was deprecated as of elasticsearch 5.0. Distance aggregations or sorting should be used instead.
+
+Filters documents that exists within a range from a specific point:
+
+## Simple example
+
+```JSON
+{
+    "query": {
+        "bool" : {
+            "must" : {
+                "match_all" : {}
+            },
+            "filter" : {
+                "geo_distance_range" : {
+                    "from" : "200km",
+                    "to" : "400km",
+                    "pin.location" : {
+                        "lat" : 40,
+                        "lon" : -70
+                    }
+                }
+            }
+        }
+    }
+}
+```
+
+In DSL:
+
+```php
+$search = new Search();
+$boolQuery = new BoolQuery();
+$boolQuery->add(new MatchAllQuery());
+$geoQuery = new GeoDistanceQuery(
+    'pin.location', 
+    ['from' => '200km', 'to' => '400km'], 
+    ['lat' => 40, 'lon' => -70]
+);
+$boolQuery->add($geoQuery, BoolQuery::FILTER);
+$search->addQuery($boolQuery);
+
+$queryArray = $search->toArray();
+```
+
+[1]: https://www.elastic.co/guide/en/elasticsearch/reference/current/query-dsl-geo-distance-range-query.html
diff --git a/docs/Query/Geo/GeoPolygon.md b/docs/Query/Geo/GeoPolygon.md
new file mode 100644
index 0000000000000000000000000000000000000000..d2e75c03c009a3ffd23391b2962fa74f89b8e6ce
--- /dev/null
+++ b/docs/Query/Geo/GeoPolygon.md
@@ -0,0 +1,50 @@
+# Geo Polygon Query
+
+> More info about geo polygon query is in the [official elasticsearch docs][1]
+
+A query allowing to include hits that only fall within a polygon of points. Here is an example:
+
+## Simple example
+
+```JSON
+{
+    "query": {
+        "bool" : {
+            "must" : {
+                "match_all" : {}
+            },
+            "filter" : {
+                "geo_polygon" : {
+                    "person.location" : {
+                        "points" : [
+                        {"lat" : 40, "lon" : -70},
+                        {"lat" : 30, "lon" : -80},
+                        {"lat" : 20, "lon" : -90}
+                        ]
+                    }
+                }
+            }
+        }
+    }
+}
+```
+
+In DSL:
+
+```php
+$points = [
+    ['lat' => 40, 'lon' => -70],
+    ['lat' => 30, 'lon' => -80],
+    ['lat' => 20, 'lon' => -90],
+];
+$search = new Search();
+$boolQuery = new BoolQuery();
+$boolQuery->add(new MatchAllQuery());
+$geoQuery = new GeoPolygonQuery('person.location', $points);
+$boolQuery->add($geoQuery, BoolQuery::FILTER);
+$search->addQuery($boolQuery);
+
+$queryArray = $search->toArray();
+```
+
+[1]: https://www.elastic.co/guide/en/elasticsearch/reference/current/query-dsl-geo-polygon-query.html
diff --git a/docs/Query/Geo/GeoShape.md b/docs/Query/Geo/GeoShape.md
new file mode 100644
index 0000000000000000000000000000000000000000..f063e2d83a71aa56732bbdec2bb154f8962846fa
--- /dev/null
+++ b/docs/Query/Geo/GeoShape.md
@@ -0,0 +1 @@
+Documentation in progress...
\ No newline at end of file
diff --git a/docs/Query/HasChild.md b/docs/Query/Joining/HasChild.md
similarity index 100%
rename from docs/Query/HasChild.md
rename to docs/Query/Joining/HasChild.md
diff --git a/docs/Query/HasParent.md b/docs/Query/Joining/HasParent.md
similarity index 100%
rename from docs/Query/HasParent.md
rename to docs/Query/Joining/HasParent.md
diff --git a/docs/Query/Nested.md b/docs/Query/Joining/Nested.md
similarity index 100%
rename from docs/Query/Nested.md
rename to docs/Query/Joining/Nested.md
diff --git a/docs/Query/SpanContaining.md b/docs/Query/Span/SpanContaining.md
similarity index 100%
rename from docs/Query/SpanContaining.md
rename to docs/Query/Span/SpanContaining.md
diff --git a/docs/Query/Span/SpanFirst.md b/docs/Query/Span/SpanFirst.md
new file mode 100644
index 0000000000000000000000000000000000000000..536cc7f117bd5abacdbd60752a0f6d80789ba5c8
--- /dev/null
+++ b/docs/Query/Span/SpanFirst.md
@@ -0,0 +1,31 @@
+# Span First Query
+
+> More info about Span First query is in the [official elasticsearch docs][1]
+
+Matches spans near the beginning of a field. The span first query maps to Lucene SpanFirstQuery. Here is an example:
+
+```JSON
+{
+    "query": {
+        "span_first" : {
+            "match" : {
+                "span_term" : { "user" : "kimchy" }
+            },
+            "end" : 3
+        }
+    }
+}
+```
+
+And now the query via DSL:
+
+```php
+$search = new Search();
+$query = new SpanFirstQuery(new SpanTermQuery('user', 'kimchy'), 3);
+$search->addQuery($query);
+
+$search->toArray();
+```
+
+
+[1]: https://www.elastic.co/guide/en/elasticsearch/reference/current/query-dsl-span-first-query.html
diff --git a/docs/Query/Span/SpanMultiTerm.md b/docs/Query/Span/SpanMultiTerm.md
new file mode 100644
index 0000000000000000000000000000000000000000..2ab25335d8bab6162b76451def8827f71c48caa5
--- /dev/null
+++ b/docs/Query/Span/SpanMultiTerm.md
@@ -0,0 +1,32 @@
+# Span Multi Term Query
+
+> More info about span multi term query is in the [official elasticsearch docs][1]
+
+The span_multi query allows you to wrap a multi term query (one of wildcard, fuzzy, prefix, range or regexp query) as a span query, so it can be nested. Example:
+
+## Simple example
+
+```JSON
+{
+    "query": {
+        "span_multi":{
+            "match":{
+                "prefix" : { "user" :  { "value" : "ki" } }
+            }
+        }
+    }
+}
+```
+
+In DSL:
+
+```php
+$search = new Search();
+$query = new PrefixQuery('user', 'ki');
+$spanMultiTermQuery = new SpanMultiTermQuery($query);
+$search->addQuery($spanMultiTermQuery);
+
+$queryArray = $search->toArray();
+```
+
+[1]: https://www.elastic.co/guide/en/elasticsearch/reference/current/query-dsl-span-multi-term-query.html
diff --git a/docs/Query/Span/SpanNear.md b/docs/Query/Span/SpanNear.md
new file mode 100644
index 0000000000000000000000000000000000000000..f063e2d83a71aa56732bbdec2bb154f8962846fa
--- /dev/null
+++ b/docs/Query/Span/SpanNear.md
@@ -0,0 +1 @@
+Documentation in progress...
\ No newline at end of file
diff --git a/docs/Query/Span/SpanNot.md b/docs/Query/Span/SpanNot.md
new file mode 100644
index 0000000000000000000000000000000000000000..f063e2d83a71aa56732bbdec2bb154f8962846fa
--- /dev/null
+++ b/docs/Query/Span/SpanNot.md
@@ -0,0 +1 @@
+Documentation in progress...
\ No newline at end of file
diff --git a/docs/Query/Span/SpanOr.md b/docs/Query/Span/SpanOr.md
new file mode 100644
index 0000000000000000000000000000000000000000..f063e2d83a71aa56732bbdec2bb154f8962846fa
--- /dev/null
+++ b/docs/Query/Span/SpanOr.md
@@ -0,0 +1 @@
+Documentation in progress...
\ No newline at end of file
diff --git a/docs/Query/Span/SpanTerm.md b/docs/Query/Span/SpanTerm.md
new file mode 100644
index 0000000000000000000000000000000000000000..f063e2d83a71aa56732bbdec2bb154f8962846fa
--- /dev/null
+++ b/docs/Query/Span/SpanTerm.md
@@ -0,0 +1 @@
+Documentation in progress...
\ No newline at end of file
diff --git a/docs/Query/SpanWithin.md b/docs/Query/Span/SpanWithin.md
similarity index 100%
rename from docs/Query/SpanWithin.md
rename to docs/Query/Span/SpanWithin.md
diff --git a/docs/Query/MoreLikeThis.md b/docs/Query/Specialized/MoreLikeThis.md
similarity index 100%
rename from docs/Query/MoreLikeThis.md
rename to docs/Query/Specialized/MoreLikeThis.md
diff --git a/docs/Query/Specialized/Script.md b/docs/Query/Specialized/Script.md
new file mode 100644
index 0000000000000000000000000000000000000000..f063e2d83a71aa56732bbdec2bb154f8962846fa
--- /dev/null
+++ b/docs/Query/Specialized/Script.md
@@ -0,0 +1 @@
+Documentation in progress...
\ No newline at end of file
diff --git a/docs/Query/Template.md b/docs/Query/Specialized/Template.md
similarity index 100%
rename from docs/Query/Template.md
rename to docs/Query/Specialized/Template.md
diff --git a/docs/Query/TermLevel/Exists.md b/docs/Query/TermLevel/Exists.md
new file mode 100644
index 0000000000000000000000000000000000000000..f063e2d83a71aa56732bbdec2bb154f8962846fa
--- /dev/null
+++ b/docs/Query/TermLevel/Exists.md
@@ -0,0 +1 @@
+Documentation in progress...
\ No newline at end of file
diff --git a/docs/Query/Fuzzy.md b/docs/Query/TermLevel/Fuzzy.md
similarity index 100%
rename from docs/Query/Fuzzy.md
rename to docs/Query/TermLevel/Fuzzy.md
diff --git a/docs/Query/Ids.md b/docs/Query/TermLevel/Ids.md
similarity index 100%
rename from docs/Query/Ids.md
rename to docs/Query/TermLevel/Ids.md
diff --git a/docs/Query/Prefix.md b/docs/Query/TermLevel/Prefix.md
similarity index 100%
rename from docs/Query/Prefix.md
rename to docs/Query/TermLevel/Prefix.md
diff --git a/docs/Query/Range.md b/docs/Query/TermLevel/Range.md
similarity index 100%
rename from docs/Query/Range.md
rename to docs/Query/TermLevel/Range.md
diff --git a/docs/Query/Regexp.md b/docs/Query/TermLevel/Regexp.md
similarity index 97%
rename from docs/Query/Regexp.md
rename to docs/Query/TermLevel/Regexp.md
index d698b004f93bb70aa8c60c7860bc8f1f346aa938..f7b7856d63c7a74f793e9a8421bb7b2c893e630b 100644
--- a/docs/Query/Regexp.md
+++ b/docs/Query/TermLevel/Regexp.md
@@ -8,7 +8,7 @@ The regexp query allows you to use regular expression term queries.
 
 ```JSON
 {
-    "filter": {
+    "query": {
         "regexp":{
             "name.first" : "s.*y"
         }
diff --git a/docs/Query/Term.md b/docs/Query/TermLevel/Term.md
similarity index 100%
rename from docs/Query/Term.md
rename to docs/Query/TermLevel/Term.md
diff --git a/docs/Query/Terms.md b/docs/Query/TermLevel/Terms.md
similarity index 100%
rename from docs/Query/Terms.md
rename to docs/Query/TermLevel/Terms.md
diff --git a/docs/Query/TermLevel/Type.md b/docs/Query/TermLevel/Type.md
new file mode 100644
index 0000000000000000000000000000000000000000..f063e2d83a71aa56732bbdec2bb154f8962846fa
--- /dev/null
+++ b/docs/Query/TermLevel/Type.md
@@ -0,0 +1 @@
+Documentation in progress...
\ No newline at end of file
diff --git a/docs/Query/Wildcard.md b/docs/Query/TermLevel/Wildcard.md
similarity index 100%
rename from docs/Query/Wildcard.md
rename to docs/Query/TermLevel/Wildcard.md
diff --git a/docs/Query/index.md b/docs/Query/index.md
deleted file mode 100644
index 29cc1212694597163a2b5e755eb691f433b36fff..0000000000000000000000000000000000000000
--- a/docs/Query/index.md
+++ /dev/null
@@ -1,55 +0,0 @@
-# Query
-
-Objective query builder represents all available [Elasticsearch queries][1].
-
-To form a query you have to create `Search` object. See below an example of match all query usage.
-
-```php
-$search = new Search();
-$matchAllQuery = new MatchAllQuery();
-$search->addQuery($matchAllQuery);
-$queryArray = $search->toArray();
-```
-
-Query handles are necessary little things like where to put `\stdClass` and where to simple array. So by using DSL builder you can be always sure that it will form a correct query.
-
-Here's `$queryArray` var_dump:
-
-```php
-//$queryArray content
-'query' =>
-    [
-      'match_all' => \stdClass(),
-    ]
-```
-
-For more information how to combine search queries take a look at [How to search](../HowTo/HowToSearch.md) chapter.
-
-
-## Queries:
- - [Bool](Bool.md)
- - [Boosting](Boosting.md)
- - [Common terms](CommonTerms.md)
- - [Constant Score](ConstantScore.md)
- - [DisMax](DisMax.md)
- - [Function score](FunctionScore.md)
- - [Fuzzy](Fuzzy.md)
- - [Has child](HasChild.md)
- - [Has parent](HasParent.md)
- - [Ids](Ids.md)
- - [Indices](Indices.md)
- - [Match all](MatchAll.md)
- - [Match](Match.md)
- - [More like this](MoreLikeThis.md)
- - [Multi match](MultiMatch.md)
- - [Nested](Nested.md)
- - [Prefix](Prefix.md)
- - [Query string](QueryString.md)
- - [Range](Range.md)
- - [Regexp](Regexp.md)
- - [Simple query string](SimpleQueryString.md)
- - [Term](Term.md)
- - [Terms](Terms.md)
- - [Wildcard](Wildcard.md)
-
-[1]: https://www.elastic.co/guide/en/elasticsearch/reference/current/query-dsl-queries.html
diff --git a/src/Query/Geo/GeoDistanceRangeQuery.php b/src/Query/Geo/GeoDistanceRangeQuery.php
index 8cced0c46a33eea235edb06872764709c5e62193..250cef549427e1a46c3e8715dc8b805cfd6c4466 100644
--- a/src/Query/Geo/GeoDistanceRangeQuery.php
+++ b/src/Query/Geo/GeoDistanceRangeQuery.php
@@ -18,6 +18,8 @@ use ONGR\ElasticsearchDSL\ParametersTrait;
  * Represents Elasticsearch "geo_distance_range" query.
  *
  * @link https://www.elastic.co/guide/en/elasticsearch/reference/current/query-dsl-geo-distance-range-query.html
+ *
+ * @deprecated The query is deprecated as of Elasticsearch 5.0 will still be supported for indices created before 5.0
  */
 class GeoDistanceRangeQuery implements BuilderInterface
 {