diff --git a/.github/workflows/main.yml b/.github/workflows/main.yml
index b21527b5dcb96e006ab7c5fac6fe2350e8680475..2276d4fed1230fa503ef6de6f5cfa8ec7f227be6 100644
--- a/.github/workflows/main.yml
+++ b/.github/workflows/main.yml
@@ -11,22 +11,20 @@ defaults:
 jobs:
   build:
     runs-on: ubuntu-latest
+    services:
+      elasticsearch:
+        image: elasticsearch:8.9.0
+        ports:
+          - 9200:9200
+        env:
+          discovery.type: 'single-node'
+          xpack.security.enabled: 'false'
+        options: --health-cmd="curl http://localhost:9200/_cluster/health" --health-interval=10s --health-timeout=5s --health-retries=5
+
     steps:
       - name: Checkout code
         uses: actions/checkout@v3
 
-#      - name: Configure sysctl limits
-#        run: |
-#          # sudo swapoff -a
-#          sudo sysctl -w vm.swappiness=1
-#          sudo sysctl -w fs.file-max=262144
-#          sudo sysctl -w vm.max_map_count=262144
-
-#      - name: Runs Elasticsearch
-#        uses: elastic/elastic-github-actions/elasticsearch@master
-#        with:
-#          stack-version: 8.9.0
-
       - name: Install composer and dependencies
         uses: php-actions/composer@v6
 
diff --git a/Makefile b/Makefile
index 13345fc3cab8dde4b0d737469215c9383a4021ef..14dfa1e122bb68c42097f5538212fc6a7085c085 100644
--- a/Makefile
+++ b/Makefile
@@ -8,4 +8,5 @@ es::
           -e ES_JAVA_OPTS="-Xms1g -Xmx1g"\
           -e xpack.security.enabled=false \
           -it \
+          --rm \
           docker.elastic.co/elasticsearch/elasticsearch:8.9.0
\ No newline at end of file
diff --git a/composer.json b/composer.json
index f96476ae665e7bac35469e92860f42ccc0653cb1..fe96a67f78a95002af0f38cfbcf0be0c4d0b5340 100644
--- a/composer.json
+++ b/composer.json
@@ -44,5 +44,10 @@
         "allow-plugins": {
             "php-http/discovery": true
         }
+    },
+    "scripts": {
+        "run-tests": [
+            "XDEBUG_MODE=coverage vendor/bin/phpunit --coverage-text"
+        ]
     }
 }
diff --git a/phpunit.xml.dist b/phpunit.xml.dist
index b3b52c086f4d09560b426f4034d02cc5ef6b4fb1..0b3983843a71ed5320bfe26a161dbdea8bab18b7 100644
--- a/phpunit.xml.dist
+++ b/phpunit.xml.dist
@@ -11,12 +11,12 @@
         <testsuite name="Unit">
             <directory>./tests/Unit/</directory>
         </testsuite>
-        <!--        <testsuite name="Functional">-->
-        <!--            <directory>./tests/Functional/</directory>-->
-        <!--        </testsuite>-->
-        <!--        <testsuite name="All">-->
-        <!--            <directory>./tests/</directory>-->
-        <!--        </testsuite>-->
+        <testsuite name="Functional">
+            <directory>./tests/Functional/</directory>
+        </testsuite>
+        <testsuite name="All">
+            <directory>./tests/</directory>
+        </testsuite>
     </testsuites>
     <logging/>
     <source>
diff --git a/src/Aggregation/AbstractAggregation.php b/src/Aggregation/AbstractAggregation.php
index 418606ff23fa76019717a60ceaca9266e30df823..b9d06e5f3ba9bf145c33448a5431e548ace51dfb 100644
--- a/src/Aggregation/AbstractAggregation.php
+++ b/src/Aggregation/AbstractAggregation.php
@@ -12,6 +12,7 @@
 namespace ONGR\ElasticsearchDSL\Aggregation;
 
 use ONGR\ElasticsearchDSL\BuilderBag;
+use ONGR\ElasticsearchDSL\BuilderInterface;
 use ONGR\ElasticsearchDSL\NameAwareTrait;
 use ONGR\ElasticsearchDSL\NamedBuilderInterface;
 use ONGR\ElasticsearchDSL\ParametersTrait;
@@ -24,37 +25,23 @@ abstract class AbstractAggregation implements NamedBuilderInterface
     use ParametersTrait;
     use NameAwareTrait;
 
-    /**
-     * @var string
-     */
-    private $field;
-
+    private ?string $field = null;
     private ?BuilderBag $aggregations = null;
 
     /**
      * Inner aggregations container init.
-     *
-     * @param string $name
      */
     public function __construct(string $name)
     {
         $this->setName($name);
     }
 
-    /**
-     * @return string
-     */
-    public function getField()
+    public function getField(): ?string
     {
         return $this->field;
     }
 
-    /**
-     * @param string $field
-     *
-     * @return $this
-     */
-    public function setField($field)
+    public function setField(?string $field): static
     {
         $this->field = $field;
 
@@ -63,11 +50,8 @@ abstract class AbstractAggregation implements NamedBuilderInterface
 
     /**
      * Adds a sub-aggregation.
-     *
-     *
-     * @return $this
      */
-    public function addAggregation(AbstractAggregation $abstractAggregation)
+    public function addAggregation(AbstractAggregation $abstractAggregation): static
     {
         if (!$this->aggregations instanceof BuilderBag) {
             $this->aggregations = $this->createBuilderBag();
@@ -80,10 +64,8 @@ abstract class AbstractAggregation implements NamedBuilderInterface
 
     /**
      * Creates BuilderBag new instance.
-     *
-     * @return BuilderBag
      */
-    private function createBuilderBag()
+    private function createBuilderBag(): BuilderBag
     {
         return new BuilderBag();
     }
@@ -91,10 +73,8 @@ abstract class AbstractAggregation implements NamedBuilderInterface
     /**
      * Returns sub aggregation.
      * @param string $name Aggregation name to return.
-     *
-     * @return \ONGR\ElasticsearchDSL\BuilderInterface
      */
-    public function getAggregation($name)
+    public function getAggregation(string $name): ?BuilderInterface
     {
         if ($this->aggregations && $this->aggregations->has($name)) {
             return $this->aggregations->get($name);
@@ -138,10 +118,8 @@ abstract class AbstractAggregation implements NamedBuilderInterface
 
     /**
      * Process all nested aggregations.
-     *
-     * @return array
      */
-    protected function collectNestedAggregations()
+    protected function collectNestedAggregations(): array
     {
         $result = [];
         /** @var AbstractAggregation $aggregation */
diff --git a/src/Aggregation/Bucketing/DateHistogramAggregation.php b/src/Aggregation/Bucketing/DateHistogramAggregation.php
index f659c236518aa121d057ae49eb42199374be297c..ef91d66469d09e5c1f65de31d40552b6d5af52cc 100644
--- a/src/Aggregation/Bucketing/DateHistogramAggregation.php
+++ b/src/Aggregation/Bucketing/DateHistogramAggregation.php
@@ -23,18 +23,23 @@ class DateHistogramAggregation extends AbstractAggregation
 {
     use BucketingTrait;
 
-    protected ?string $interval;
-    protected ?string $format;
+    protected ?string $calendarInterval = null;
+    protected ?string $fixedInterval = null;
+    protected ?string $format = null;
 
     /**
      * Inner aggregations container init.
      */
-    public function __construct(string $name, ?string $field = null, ?string $interval = null, ?string $format = null)
-    {
+    public function __construct(
+        string $name,
+        ?string $field = null,
+        ?string $calendarInterval = null,
+        ?string $format = null
+    ) {
         parent::__construct($name);
 
         $this->setField($field);
-        $this->setInterval($interval);
+        $this->setCalendarInterval($calendarInterval);
         $this->setFormat($format);
     }
 
@@ -45,6 +50,34 @@ class DateHistogramAggregation extends AbstractAggregation
         return $this;
     }
 
+    public function getCalendarInterval(): ?string
+    {
+        return $this->calendarInterval;
+    }
+
+    public function setCalendarInterval(?string $calendarInterval): static
+    {
+        $this->calendarInterval = $calendarInterval;
+
+        return $this;
+    }
+
+    /**
+     * @return string|null
+     */
+    public function getFixedInterval(): ?string
+    {
+        return $this->fixedInterval;
+    }
+
+    /**
+     * @param string|null $fixedInterval
+     */
+    public function setFixedInterval(?string $fixedInterval): void
+    {
+        $this->fixedInterval = $fixedInterval;
+    }
+
     /**
      * {@inheritdoc}
      */
@@ -58,15 +91,20 @@ class DateHistogramAggregation extends AbstractAggregation
      */
     public function getArray(): array|\stdClass
     {
-        if (!$this->getField() || !$this->getInterval()) {
-            throw new \LogicException('Date histogram aggregation must have field and interval set.');
+        if (!$this->getField() || !($this->getCalendarInterval() || $this->getFixedInterval())) {
+            throw new \LogicException('Date histogram aggregation must have field and calendar_interval set.');
         }
 
         $out = [
             'field' => $this->getField(),
-            'interval' => $this->getInterval(),
         ];
 
+        if ($this->getCalendarInterval()) {
+            $out['calendar_interval'] = $this->getCalendarInterval();
+        } elseif ($this->getFixedInterval()) {
+            $out['fixed_interval'] = $this->getFixedInterval();
+        }
+
         if (!empty($this->format)) {
             $out['format'] = $this->format;
         }
@@ -74,15 +112,5 @@ class DateHistogramAggregation extends AbstractAggregation
         return $out;
     }
 
-    public function getInterval(): ?string
-    {
-        return $this->interval;
-    }
-
-    public function setInterval(?string $interval): static
-    {
-        $this->interval = $interval;
 
-        return $this;
-    }
 }
diff --git a/src/Aggregation/Bucketing/FilterAggregation.php b/src/Aggregation/Bucketing/FilterAggregation.php
index 0a751d8b2854210dcdd38ec61b8a7a854ae42e3b..7b49d2c727d80ce0cb26273336b9f12ab4de4e70 100644
--- a/src/Aggregation/Bucketing/FilterAggregation.php
+++ b/src/Aggregation/Bucketing/FilterAggregation.php
@@ -41,7 +41,7 @@ class FilterAggregation extends AbstractAggregation
     /**
      * {@inheritdoc}
      */
-    public function setField($field): void
+    public function setField(?string $field): static
     {
         throw new \LogicException("Filter aggregation, doesn't support `field` parameter");
     }
diff --git a/src/Aggregation/Bucketing/GlobalAggregation.php b/src/Aggregation/Bucketing/GlobalAggregation.php
index 92f92210f48fa17002d93946587d114d06c1a638..981aef2b55997a277d5deb493c91be435786de56 100644
--- a/src/Aggregation/Bucketing/GlobalAggregation.php
+++ b/src/Aggregation/Bucketing/GlobalAggregation.php
@@ -26,7 +26,7 @@ class GlobalAggregation extends AbstractAggregation
     /**
      * {@inheritdoc}
      */
-    public function setField($field): void
+    public function setField(?string $field): static
     {
         throw new \LogicException("Global aggregation, doesn't support `field` parameter");
     }
diff --git a/src/Aggregation/Bucketing/HistogramAggregation.php b/src/Aggregation/Bucketing/HistogramAggregation.php
index 18bc1a99e4073b03259f71119cf008a5aaee0626..5bb7a5d92f2c834920d386ded9601657e65a3a76 100644
--- a/src/Aggregation/Bucketing/HistogramAggregation.php
+++ b/src/Aggregation/Bucketing/HistogramAggregation.php
@@ -26,59 +26,26 @@ class HistogramAggregation extends AbstractAggregation
     final public const DIRECTION_ASC = 'asc';
     final public const DIRECTION_DESC = 'desc';
 
-    /**
-     * @var int
-     */
-    protected $interval;
-
-    /**
-     * @var int
-     */
-    protected $minDocCount;
-
-    /**
-     * @var array
-     */
-    protected $extendedBounds;
-
-    /**
-     * @var string
-     */
-    protected $orderMode;
-
-    /**
-     * @var string
-     */
-    protected $orderDirection;
-
-    /**
-     * @var bool
-     */
-    protected $keyed;
+    protected ?int $interval = null;
+    protected ?int $minDocCount = null;
+    protected ?array $extendedBounds = null;
+    protected ?string $orderMode = null;
+    protected ?string $orderDirection = null;
+    protected ?bool $keyed = null;
 
     /**
      * Inner aggregations container init.
-     *
-     * @param string $name
-     * @param string $field
-     * @param int $interval
-     * @param int $minDocCount
-     * @param string $orderMode
-     * @param string $orderDirection
-     * @param int $extendedBoundsMin
-     * @param int $extendedBoundsMax
-     * @param bool $keyed
      */
     public function __construct(
-        $name,
-        $field = null,
-        $interval = null,
-        $minDocCount = null,
-        $orderMode = null,
-        $orderDirection = self::DIRECTION_ASC,
-        $extendedBoundsMin = null,
-        $extendedBoundsMax = null,
-        $keyed = null
+        string $name,
+        ?string $field = null,
+        ?int $interval = null,
+        ?int $minDocCount = null,
+        ?string $orderMode = null,
+        ?string $orderDirection = self::DIRECTION_ASC,
+        ?int $extendedBoundsMin = null,
+        ?int $extendedBoundsMax = null,
+        ?bool $keyed = null
     ) {
         parent::__construct($name);
 
@@ -92,13 +59,8 @@ class HistogramAggregation extends AbstractAggregation
 
     /**
      * Sets buckets ordering.
-     *
-     * @param string $mode
-     * @param string $direction
-     *
-     * @return $this
      */
-    public function setOrder($mode, $direction = self::DIRECTION_ASC)
+    public function setOrder(?string $mode, ?string $direction = self::DIRECTION_ASC): static
     {
         $this->orderMode = $mode;
         $this->orderDirection = $direction;
@@ -135,89 +97,63 @@ class HistogramAggregation extends AbstractAggregation
         return $out;
     }
 
-    /**
-     * @return int
-     */
-    public function getInterval()
+    public function getInterval(): ?int
     {
         return $this->interval;
     }
 
-    /**
-     * @param int $interval
-     *
-     * @return $this
-     */
-    public function setInterval($interval)
+    public function setInterval(?int $interval): static
     {
         $this->interval = $interval;
 
         return $this;
     }
 
-    /**
-     * @return int
-     */
-    public function getMinDocCount()
+    public function getMinDocCount(): ?int
     {
         return $this->minDocCount;
     }
 
     /**
      * Set limit for document count buckets should have.
-     *
-     * @param int $minDocCount
-     *
-     * @return $this
      */
-    public function setMinDocCount($minDocCount)
+    public function setMinDocCount(?int $minDocCount): static
     {
         $this->minDocCount = $minDocCount;
 
         return $this;
     }
 
-    /**
-     * @return array
-     */
-    public function getExtendedBounds()
+    public function getExtendedBounds(): ?array
     {
         return $this->extendedBounds;
     }
 
-    /**
-     * @param int $min
-     * @param int $max
-     *
-     * @return $this
-     */
-    public function setExtendedBounds($min = null, $max = null)
+    public function setExtendedBounds(?int $min = null, ?int $max = null): static
     {
-        $bounds = [
-            'min' => $min ?? '',
-            'max' => $max ?? '',
-        ];
+        $bounds = array_filter(
+            [
+                'min' => $min,
+                'max' => $max,
+            ],
+            static function ($item) {
+                return $item !== null;
+            }
+        );
         $this->extendedBounds = $bounds;
 
         return $this;
     }
 
-    /**
-     * @return bool
-     */
-    public function isKeyed()
+    public function isKeyed(): ?bool
     {
         return $this->keyed;
     }
 
     /**
      * Get response as a hash instead keyed by the buckets keys.
-     *
-     * @param bool $keyed
-     *
-     * @return $this
      */
-    public function setKeyed($keyed)
+    public function setKeyed(?bool $keyed): static
     {
         $this->keyed = $keyed;
 
@@ -227,7 +163,7 @@ class HistogramAggregation extends AbstractAggregation
     /**
      * @return array
      */
-    public function getOrder()
+    public function getOrder(): ?array
     {
         if ($this->orderMode && $this->orderDirection) {
             return [$this->orderMode => $this->orderDirection];
@@ -244,7 +180,7 @@ class HistogramAggregation extends AbstractAggregation
      *
      * @throws \LogicException
      */
-    protected function checkRequiredParameters($data, $required)
+    protected function checkRequiredParameters(array $data, array $required): void
     {
         if (count(array_intersect_key(array_flip($required), $data)) !== count($required)) {
             throw new \LogicException('Histogram aggregation must have field and interval set.');
diff --git a/src/Aggregation/Pipeline/MovingAverageAggregation.php b/src/Aggregation/Pipeline/MovingAverageAggregation.php
deleted file mode 100644
index e3ddf7805133340d6ac164fc7bc062df9e21eaf6..0000000000000000000000000000000000000000
--- a/src/Aggregation/Pipeline/MovingAverageAggregation.php
+++ /dev/null
@@ -1,28 +0,0 @@
-<?php
-
-/*
- * This file is part of the ONGR package.
- *
- * (c) NFQ Technologies UAB <info@nfq.com>
- *
- * For the full copyright and license information, please view the LICENSE
- * file that was distributed with this source code.
- */
-
-namespace ONGR\ElasticsearchDSL\Aggregation\Pipeline;
-
-/**
- * Class representing Max Bucket Pipeline Aggregation.
- *
- * @link https://goo.gl/8gIfok
- */
-class MovingAverageAggregation extends AbstractPipelineAggregation
-{
-    /**
-     * {@inheritdoc}
-     */
-    public function getType(): string
-    {
-        return 'moving_avg';
-    }
-}
diff --git a/src/ParametersTrait.php b/src/ParametersTrait.php
index 1e16940ecc505b4b579c90d78df1ce8529af115f..be21e9fb521a8100829bf38e802b358de9196b08 100644
--- a/src/ParametersTrait.php
+++ b/src/ParametersTrait.php
@@ -21,11 +21,13 @@ trait ParametersTrait
     /**
      * Removes parameter.
      */
-    public function removeParameter(string $name): void
+    public function removeParameter(string $name): static
     {
         if ($this->hasParameter($name)) {
             unset($this->parameters[$name]);
         }
+
+        return $this;
     }
 
     /**
@@ -59,9 +61,11 @@ trait ParametersTrait
         return $this;
     }
 
-    public function addParameter(string $name, mixed $value): void
+    public function addParameter(string $name, mixed $value): static
     {
         $this->parameters[$name] = $value;
+
+        return $this;
     }
 
     /**
diff --git a/src/Query/Compound/BoolQuery.php b/src/Query/Compound/BoolQuery.php
index 648a2ec3e972e7496cc70c837543ca8ac43cf1af..dd51657adc67ba70688851eaa43512848fdf88b8 100644
--- a/src/Query/Compound/BoolQuery.php
+++ b/src/Query/Compound/BoolQuery.php
@@ -55,7 +55,7 @@ class BoolQuery implements BuilderInterface
      *
      * @throws \UnexpectedValueException
      */
-    public function add(BuilderInterface $query, $type = self::MUST, $key = null)
+    public function add(BuilderInterface $query, string $type = self::MUST, mixed $key = null): mixed
     {
         if (!in_array($type, [self::MUST, self::MUST_NOT, self::SHOULD, self::FILTER])) {
             throw new \UnexpectedValueException(sprintf('The bool operator %s is not supported', $type));
@@ -72,12 +72,8 @@ class BoolQuery implements BuilderInterface
 
     /**
      * Returns the query instances (by bool type).
-     *
-     * @param string|null $boolType
-     *
-     * @return array
      */
-    public function getQueries($boolType = null)
+    public function getQueries(?string $boolType = null): array
     {
         if ($boolType === null) {
             $queries = [];
diff --git a/src/Query/Compound/FunctionScoreQuery.php b/src/Query/Compound/FunctionScoreQuery.php
index 7b8387607f393d732747a6b189bc30498fbadd2b..f9a3a6adddb710890700f43f103ca727cd9d6365 100644
--- a/src/Query/Compound/FunctionScoreQuery.php
+++ b/src/Query/Compound/FunctionScoreQuery.php
@@ -23,9 +23,6 @@ class FunctionScoreQuery implements BuilderInterface
 {
     use ParametersTrait;
 
-    /**
-     * @var mixed[][]|null
-     */
     private ?array $functions = null;
 
     public function __construct(private readonly BuilderInterface $query, array $parameters = [])
@@ -35,8 +32,6 @@ class FunctionScoreQuery implements BuilderInterface
 
     /**
      * Returns the query instance.
-     *
-     * @return BuilderInterface object
      */
     public function getQuery(): BuilderInterface
     {
@@ -45,19 +40,14 @@ class FunctionScoreQuery implements BuilderInterface
 
     /**
      * Creates field_value_factor function.
-     *
-     * @param string $field
-     * @param float $factor
-     * @param string $modifier
-     * @return $this
      */
     public function addFieldValueFactorFunction(
-        $field,
-        $factor,
-        $modifier = 'none',
+        string $field,
+        float $factor,
+        string $modifier = 'none',
         BuilderInterface $query = null,
         mixed $missing = null
-    ) {
+    ): static {
         $function = [
             'field_value_factor' => array_filter(
                 [
@@ -111,21 +101,15 @@ class FunctionScoreQuery implements BuilderInterface
 
     /**
      * Add decay function to function score. Weight and query are optional.
-     *
-     * @param string $type
-     * @param string $field
-     * @param int $weight
-     *
-     * @return $this
      */
     public function addDecayFunction(
-        $type,
-        $field,
+        string $type,
+        string $field,
         array $function,
         array $options = [],
         BuilderInterface $query = null,
-        $weight = null
-    ) {
+        ?int $weight = null
+    ): static {
         $function = array_filter(
             [
                 $type => array_merge(
@@ -145,12 +129,8 @@ class FunctionScoreQuery implements BuilderInterface
 
     /**
      * Adds function to function score without decay function. Influence search score only for specific query.
-     *
-     * @param float $weight
-     *
-     * @return $this
      */
-    public function addWeightFunction($weight, BuilderInterface $query = null)
+    public function addWeightFunction(float $weight, BuilderInterface $query = null): static
     {
         $function = [
             'weight' => $weight,
@@ -165,11 +145,8 @@ class FunctionScoreQuery implements BuilderInterface
 
     /**
      * Adds random score function. Seed is optional.
-     *
-     *
-     * @return $this
      */
-    public function addRandomFunction(mixed $seed = null, BuilderInterface $query = null)
+    public function addRandomFunction(mixed $seed = null, BuilderInterface $query = null): static
     {
         $function = [
             'random_score' => $seed ? ['seed' => $seed] : new \stdClass(),
@@ -184,17 +161,13 @@ class FunctionScoreQuery implements BuilderInterface
 
     /**
      * Adds script score function.
-     *
-     * @param string $inline
-     *
-     * @return $this
      */
     public function addScriptScoreFunction(
-        $inline,
+        string $source,
         array $params = [],
         array $options = [],
         BuilderInterface $query = null
-    ) {
+    ): static {
         $function = [
             'script_score' => [
                 'script' =>
@@ -202,7 +175,7 @@ class FunctionScoreQuery implements BuilderInterface
                         array_merge(
                             [
                                 'lang' => 'painless',
-                                'inline' => $inline,
+                                'source' => $source,
                                 'params' => $params,
                             ],
                             $options
@@ -219,11 +192,8 @@ class FunctionScoreQuery implements BuilderInterface
 
     /**
      * Adds custom simple function. You can add to the array whatever you want.
-     *
-     *
-     * @return $this
      */
-    public function addSimpleFunction(array $function)
+    public function addSimpleFunction(array $function): static
     {
         $this->functions[] = $function;
 
diff --git a/src/Query/FullText/CommonTermsQuery.php b/src/Query/FullText/CommonTermsQuery.php
deleted file mode 100644
index 4c35bb07525850cf695df851b34eb976b5989c84..0000000000000000000000000000000000000000
--- a/src/Query/FullText/CommonTermsQuery.php
+++ /dev/null
@@ -1,58 +0,0 @@
-<?php
-
-/*
- * This file is part of the ONGR package.
- *
- * (c) NFQ Technologies UAB <info@nfq.com>
- *
- * For the full copyright and license information, please view the LICENSE
- * file that was distributed with this source code.
- */
-
-namespace ONGR\ElasticsearchDSL\Query\FullText;
-
-use ONGR\ElasticsearchDSL\BuilderInterface;
-use ONGR\ElasticsearchDSL\ParametersTrait;
-
-/**
- * Represents Elasticsearch "common" query.
- *
- * @link https://www.elastic.co/guide/en/elasticsearch/reference/current/query-dsl-common-terms-query.html
- */
-class CommonTermsQuery implements BuilderInterface
-{
-    use ParametersTrait;
-
-    /**
-     * @param string $field
-     * @param string $query
-     */
-    public function __construct(private $field, private $query, array $parameters = [])
-    {
-        $this->setParameters($parameters);
-    }
-
-    /**
-     * {@inheritdoc}
-     */
-    public function toArray(): array|\stdClass
-    {
-        $query = [
-            'query' => $this->query,
-        ];
-
-        $output = [
-            $this->field => $this->processArray($query),
-        ];
-
-        return [$this->getType() => $output];
-    }
-
-    /**
-     * {@inheritdoc}
-     */
-    public function getType(): string
-    {
-        return 'common';
-    }
-}
diff --git a/src/Query/Geo/GeoShapeQuery.php b/src/Query/Geo/GeoShapeQuery.php
index 356022c59509eca2b372f04638505925ffd51d79..ed075eff726dd84eb5e0ced75957993d6a5d9b47 100644
--- a/src/Query/Geo/GeoShapeQuery.php
+++ b/src/Query/Geo/GeoShapeQuery.php
@@ -70,16 +70,9 @@ class GeoShapeQuery implements BuilderInterface
         string $field,
         string $type,
         array $coordinates,
-        $relation = self::INTERSECTS,
+        string $relation = self::INTERSECTS,
         array $parameters = []
     ): static {
-        // TODO: remove this in the next major version
-        if (is_array($relation)) {
-            $parameters = $relation;
-            $relation = self::INTERSECTS;
-            trigger_error('$parameters as parameter 4 in addShape is deprecated', E_USER_DEPRECATED);
-        }
-
         $filter = array_merge(
             $parameters,
             [
@@ -113,16 +106,9 @@ class GeoShapeQuery implements BuilderInterface
         string $type,
         string $index,
         string $path,
-        $relation = self::INTERSECTS,
+        string $relation = self::INTERSECTS,
         array $parameters = []
     ): static {
-        // TODO: remove this in the next major version
-        if (is_array($relation)) {
-            $parameters = $relation;
-            $relation = self::INTERSECTS;
-            trigger_error('$parameters as parameter 6 in addShape is deprecated', E_USER_DEPRECATED);
-        }
-
         $filter = array_merge(
             $parameters,
             [
diff --git a/src/Search.php b/src/Search.php
index 1dba4c527d4d851cbc652ca10c6e43aa9ee25871..ed78d6871807df1f5b538deb47b4afaec38c7a8a 100644
--- a/src/Search.php
+++ b/src/Search.php
@@ -35,33 +35,37 @@ use Symfony\Component\Serializer\Normalizer\CustomNormalizer;
 class Search
 {
     private static ?OrderedSerializer $serializer = null;
+
     /**
      * If you don’t need to track the total number of hits at all you can improve
      * query times by setting this option to false. Defaults to true.
      */
     private ?bool $trackTotalHits = null;
+
     /**
      * To retrieve hits from a certain offset. Defaults to 0.
      */
     private ?int $from = null;
+
     /**
      * The number of hits to return. Defaults to 10. If you do not care about getting some
      * hits back but only about the number of matches and/or aggregations, setting the value
      * to 0 will help performance.
      */
     private ?int $size = null;
+
     /**
      * Allows to control how the _source field is returned with every hit. By default
      * operations return the contents of the _source field unless you have used the
      * stored_fields parameter or if the _source field is disabled.
-     *
-     * @var bool
      */
-    private $source;
+    private bool|array|string|null $source = null;
+
     /**
      * Allows to selectively load specific stored fields for each document represented by a search hit.
      */
     private ?array $storedFields = null;
+
     /**
      * Allows to return a script evaluation (based on different fields) for each hit.
      * Script fields can work on fields that are not stored, and allow to return custom
@@ -70,6 +74,7 @@ class Search
      * to be returned from it (can be an "object" type).
      */
     private ?array $scriptFields = null;
+
     /**
      * Allows to return the doc value representation of a field for each hit. Doc value
      * fields can work on fields that are not stored. Note that if the fields parameter
@@ -78,30 +83,31 @@ class Search
      * result in more memory consumption.
      */
     private ?array $docValueFields = null;
+
     /**
      * Enables explanation for each hit on how its score was computed.
      *
      * @var bool
      */
     private ?bool $explain = null;
+
     /**
      * Returns a version for each search hit.
-     *
-     * @var bool
      */
     private ?bool $version = null;
+
     /**
      * Allows to configure different boost level per index when searching across more
-     * than one indices. This is very handy when hits coming from one index matter more
+     * than one indice. This is very handy when hits coming from one index matter more
      * than hits coming from another index (think social graph where each user has an index).
      */
     private ?array $indicesBoost = null;
+
     /**
      * Exclude documents which have a _score less than the minimum specified in min_score.
-     *
-     * @var int
      */
     private ?int $minScore = null;
+
     /**
      * Pagination of results can be done by using the from and size but the cost becomes
      * prohibitive when the deep pagination is reached. The index.max_result_window which
@@ -113,12 +119,14 @@ class Search
      * help the retrieval of the next page.
      */
     private ?array $searchAfter = null;
+
     /**
      * URI parameters alongside Request body search.
      *
      * @link https://www.elastic.co/guide/en/elasticsearch/reference/current/search-uri-request.html
      */
     private ?array $uriParams = null;
+
     /**
      * While a search request returns a single “page” of results, the scroll API can be used to retrieve
      * large numbers of results (or even all results) from a single search request, in much the same way
@@ -127,6 +135,7 @@ class Search
      * of one index into a new index with a different configuration.
      */
     private ?string $scroll = null;
+
     /**
      * @var SearchEndpointInterface[]
      */
@@ -186,12 +195,8 @@ class Search
 
     /**
      * Returns endpoint instance.
-     *
-     * @param string $type Endpoint type.
-     *
-     * @return SearchEndpointInterface
      */
-    private function getEndpoint($type)
+    private function getEndpoint(string $type): SearchEndpointInterface
     {
         if (!array_key_exists($type, $this->endpoints ?? [])) {
             $this->endpoints[$type] = SearchEndpointFactory::get($type);
@@ -244,16 +249,12 @@ class Search
     /**
      * Adds a post filter to search.
      *
-     * @param BuilderInterface $filter Filter.
      * @param string $boolType Example boolType values:
      *                                   - must
      *                                   - must_not
      *                                   - should.
-     * @param string $key
-     *
-     * @return $this.
      */
-    public function addPostFilter(BuilderInterface $filter, $boolType = BoolQuery::MUST, $key = null): static
+    public function addPostFilter(BuilderInterface $filter, string $boolType = BoolQuery::MUST, mixed $key = null): static
     {
         $this
             ->getEndpoint(PostFilterEndpoint::NAME)
@@ -276,9 +277,6 @@ class Search
 
     /**
      * Sets post filter endpoint parameters.
-     *
-     *
-     * @return $this
      */
     public function setPostFilterParameters(array $parameters): static
     {
@@ -305,7 +303,7 @@ class Search
      *
      * @return BuilderInterface[]
      */
-    public function getAggregations()
+    public function getAggregations(): array
     {
         return $this->getEndpoint(AggregationsEndpoint::NAME)->getAll();
     }
@@ -328,7 +326,7 @@ class Search
      *
      * @return BuilderInterface[]
      */
-    public function getInnerHits()
+    public function getInnerHits(): array
     {
         return $this->getEndpoint(InnerHitsEndpoint::NAME)->getAll();
     }
@@ -351,7 +349,7 @@ class Search
      *
      * @return BuilderInterface[]
      */
-    public function getSorts()
+    public function getSorts(): array
     {
         return $this->getEndpoint(SortEndpoint::NAME)->getAll();
     }
@@ -432,10 +430,7 @@ class Search
         return $this->trackTotalHits;
     }
 
-    /**
-     * @return $this
-     */
-    public function setTrackTotalHits(bool $trackTotalHits)
+    public function setTrackTotalHits(bool|int $trackTotalHits): static
     {
         $this->trackTotalHits = $trackTotalHits;
 
@@ -454,20 +449,17 @@ class Search
         return $this;
     }
 
-    /**
-     * @return bool
-     */
-    public function isSource()
+    public function isSource(): bool
+    {
+        return (bool)$this->source;
+    }
+
+    public function getSource(): bool|array|string|null
     {
         return $this->source;
     }
 
-    /**
-     * @param bool $source
-     *
-     * @return $this
-     */
-    public function setSource($source): static
+    public function setSource(bool|array|string|null $source): static
     {
         $this->source = $source;
 
@@ -502,92 +494,55 @@ class Search
         return $this->scriptFields;
     }
 
-    /**
-     * @param array $scriptFields
-     *
-     * @return $this
-     */
-    public function setScriptFields($scriptFields): static
+    public function setScriptFields(?array $scriptFields): static
     {
         $this->scriptFields = $scriptFields;
 
         return $this;
     }
 
-    /**
-     * @return array
-     */
-    public function getDocValueFields()
+    public function getDocValueFields(): ?array
     {
         return $this->docValueFields;
     }
 
-    /**
-     * @param array $docValueFields
-     *
-     * @return $this
-     */
-    public function setDocValueFields($docValueFields): static
+    public function setDocValueFields(?array $docValueFields): static
     {
         $this->docValueFields = $docValueFields;
 
         return $this;
     }
 
-    /**
-     * @return bool
-     */
-    public function isExplain()
+    public function isExplain(): ?bool
     {
         return $this->explain;
     }
 
-    /**
-     * @param bool $explain
-     *
-     * @return $this
-     */
-    public function setExplain($explain): static
+    public function setExplain(?bool $explain): static
     {
         $this->explain = $explain;
 
         return $this;
     }
 
-    /**
-     * @return bool
-     */
-    public function isVersion()
+    public function isVersion(): ?bool
     {
         return $this->version;
     }
 
-    /**
-     * @param bool $version
-     *
-     * @return $this
-     */
-    public function setVersion($version): static
+    public function setVersion(?bool $version): static
     {
         $this->version = $version;
 
         return $this;
     }
 
-    /**
-     * @return array
-     */
-    public function getIndicesBoost()
+    public function getIndicesBoost(): ?array
     {
         return $this->indicesBoost;
     }
 
-    /**
-     * @param array $indicesBoost
-     *
-     * @return $this
-     */
-    public function setIndicesBoost($indicesBoost): static
+    public function setIndicesBoost(?array $indicesBoost): static
     {
         $this->indicesBoost = $indicesBoost;
 
@@ -689,6 +644,7 @@ class Search
             'typed_keys',
             'pre_filter_shard_size',
             'ignore_unavailable',
+            'rest_total_hits_as_int',
         ])) {
             $this->uriParams[$name] = $value;
         } else {
diff --git a/src/SearchEndpoint/AbstractSearchEndpoint.php b/src/SearchEndpoint/AbstractSearchEndpoint.php
index 1a5b436d4cc570a749de8495f7742f2431e5ac1e..5d2023be017dbe4631b75b4cadb5af03c3c1ffe2 100644
--- a/src/SearchEndpoint/AbstractSearchEndpoint.php
+++ b/src/SearchEndpoint/AbstractSearchEndpoint.php
@@ -13,6 +13,7 @@ namespace ONGR\ElasticsearchDSL\SearchEndpoint;
 
 use ONGR\ElasticsearchDSL\BuilderInterface;
 use ONGR\ElasticsearchDSL\ParametersTrait;
+use ONGR\ElasticsearchDSL\Query\Compound\BoolQuery;
 use ONGR\ElasticsearchDSL\Serializer\Normalizer\AbstractNormalizable;
 
 /**
@@ -30,7 +31,7 @@ abstract class AbstractSearchEndpoint extends AbstractNormalizable implements Se
     /**
      * {@inheritdoc}
      */
-    public function add(BuilderInterface $builder, $key = null)
+    public function add(BuilderInterface $builder, mixed $key = null): mixed
     {
         if (array_key_exists($key, $this->container)) {
             throw new \OverflowException(sprintf('Builder with %s name for endpoint has already been added!', $key));
@@ -48,7 +49,7 @@ abstract class AbstractSearchEndpoint extends AbstractNormalizable implements Se
     /**
      * {@inheritdoc}
      */
-    public function addToBool(BuilderInterface $builder, ?string $boolType = null, mixed $key = null)
+    public function addToBool(BuilderInterface $builder, ?string $boolType = null, mixed $key = null): mixed
     {
         throw new \BadFunctionCallException(sprintf("Endpoint %s doesn't support bool statements", static::NAME));
     }
@@ -56,7 +57,7 @@ abstract class AbstractSearchEndpoint extends AbstractNormalizable implements Se
     /**
      * {@inheritdoc}
      */
-    public function remove($key)
+    public function remove(mixed $key): static
     {
         if ($this->has($key)) {
             unset($this->container[$key]);
@@ -70,7 +71,7 @@ abstract class AbstractSearchEndpoint extends AbstractNormalizable implements Se
      *
      * @param string $key Key to check if it exists in container.
      */
-    public function has($key): bool
+    public function has(mixed $key): bool
     {
         return array_key_exists($key, $this->container);
     }
@@ -78,7 +79,7 @@ abstract class AbstractSearchEndpoint extends AbstractNormalizable implements Se
     /**
      * {@inheritdoc}
      */
-    public function get($key)
+    public function get(mixed $key): ?BuilderInterface
     {
         if ($this->has($key)) {
             return $this->container[$key];
@@ -90,7 +91,7 @@ abstract class AbstractSearchEndpoint extends AbstractNormalizable implements Se
     /**
      * {@inheritdoc}
      */
-    public function getAll($boolType = null)
+    public function getAll(?string $boolType = null): array
     {
         return $this->container;
     }
@@ -98,7 +99,7 @@ abstract class AbstractSearchEndpoint extends AbstractNormalizable implements Se
     /**
      * {@inheritdoc}
      */
-    public function getBool()
+    public function getBool(): ?BoolQuery
     {
         throw new \BadFunctionCallException(sprintf("Endpoint %s doesn't support bool statements", static::NAME));
     }
diff --git a/src/SearchEndpoint/HighlightEndpoint.php b/src/SearchEndpoint/HighlightEndpoint.php
index 1607e0502750eba9a26b1c14f723287aa9262e80..3f24e2dc69b2e968b39fb3958271e3cc7b9335fe 100644
--- a/src/SearchEndpoint/HighlightEndpoint.php
+++ b/src/SearchEndpoint/HighlightEndpoint.php
@@ -24,15 +24,12 @@ class HighlightEndpoint extends AbstractSearchEndpoint
      */
     final public const NAME = 'highlight';
 
-    /**
-     * @var BuilderInterface
-     */
-    private $highlight;
+    private ?BuilderInterface $highlight = null;
 
     /**
-     * @var string Key for highlight storing.
+     * @var mixed Key for highlight storing.
      */
-    private $key;
+    private mixed $key;
 
     /**
      * {@inheritdoc}
@@ -42,17 +39,13 @@ class HighlightEndpoint extends AbstractSearchEndpoint
         $format = null,
         array $context = []
     ): array|string|int|float|bool|\ArrayObject|null {
-        if ($this->highlight) {
-            return $this->highlight->toArray();
-        }
-
-        return null;
+        return $this->highlight?->toArray();
     }
 
     /**
      * {@inheritdoc}
      */
-    public function add(BuilderInterface $builder, $key = null)
+    public function add(BuilderInterface $builder, mixed $key = null): mixed
     {
         if ($this->highlight) {
             throw new \OverflowException('Only one highlight can be set');
@@ -60,20 +53,19 @@ class HighlightEndpoint extends AbstractSearchEndpoint
 
         $this->key = $key;
         $this->highlight = $builder;
+
+        return $key;
     }
 
     /**
      * {@inheritdoc}
      */
-    public function getAll($boolType = null): array
+    public function getAll(?string $boolType = null): array
     {
         return [$this->key => $this->highlight];
     }
 
-    /**
-     * @return BuilderInterface
-     */
-    public function getHighlight()
+    public function getHighlight(): ?BuilderInterface
     {
         return $this->highlight;
     }
diff --git a/src/SearchEndpoint/PostFilterEndpoint.php b/src/SearchEndpoint/PostFilterEndpoint.php
index f71c30d2b952fd41d0c6736b4ff49fb9bfabf0b3..1440905837580ad074d4f5fd36bd211553776285 100644
--- a/src/SearchEndpoint/PostFilterEndpoint.php
+++ b/src/SearchEndpoint/PostFilterEndpoint.php
@@ -31,11 +31,7 @@ class PostFilterEndpoint extends QueryEndpoint
         $format = null,
         array $context = []
     ): array|string|int|float|bool|\ArrayObject|null {
-        if (!$this->getBool()) {
-            return null;
-        }
-
-        return $this->getBool()->toArray();
+        return $this->getBool()?->toArray();
     }
 
     /**
diff --git a/src/SearchEndpoint/QueryEndpoint.php b/src/SearchEndpoint/QueryEndpoint.php
index 8e3511b5f55f0992e74cc5ae6eaa72f42a94d5ad..f0774f303810608484e819cd2cc06a29ea5fb8b2 100644
--- a/src/SearchEndpoint/QueryEndpoint.php
+++ b/src/SearchEndpoint/QueryEndpoint.php
@@ -27,7 +27,6 @@ class QueryEndpoint extends AbstractSearchEndpoint implements OrderedNormalizerI
     public const NAME = 'query';
 
     private ?BoolQuery $bool = null;
-
     private bool $filtersSet = false;
 
     /**
@@ -55,7 +54,7 @@ class QueryEndpoint extends AbstractSearchEndpoint implements OrderedNormalizerI
     /**
      * {@inheritdoc}
      */
-    public function addToBool(BuilderInterface $builder, ?string $boolType = null, mixed $key = null)
+    public function addToBool(BuilderInterface $builder, ?string $boolType = null, mixed $key = null): mixed
     {
         if (!$this->bool instanceof BoolQuery) {
             $this->bool = new BoolQuery();
@@ -67,7 +66,7 @@ class QueryEndpoint extends AbstractSearchEndpoint implements OrderedNormalizerI
     /**
      * {@inheritdoc}
      */
-    public function add(BuilderInterface $builder, $key = null)
+    public function add(BuilderInterface $builder, mixed $key = null): mixed
     {
         return $this->addToBool($builder, BoolQuery::MUST, $key);
     }
@@ -83,7 +82,7 @@ class QueryEndpoint extends AbstractSearchEndpoint implements OrderedNormalizerI
     /**
      * @return BoolQuery
      */
-    public function getBool()
+    public function getBool(): ?BoolQuery
     {
         return $this->bool;
     }
@@ -91,7 +90,7 @@ class QueryEndpoint extends AbstractSearchEndpoint implements OrderedNormalizerI
     /**
      * {@inheritdoc}
      */
-    public function getAll($boolType = null)
+    public function getAll(?string $boolType = null): array
     {
         return $this->bool->getQueries($boolType);
     }
diff --git a/src/SearchEndpoint/SearchEndpointFactory.php b/src/SearchEndpoint/SearchEndpointFactory.php
index e3acf4a5c5ea84ffe847bdfdedde9fd25e90dd21..87d18ba1d9c19137fb3c03252080fee24f8a38f5 100644
--- a/src/SearchEndpoint/SearchEndpointFactory.php
+++ b/src/SearchEndpoint/SearchEndpointFactory.php
@@ -31,14 +31,9 @@ class SearchEndpointFactory
 
     /**
      * Returns a search endpoint instance.
-     *
-     * @param string $type Type of endpoint.
-     *
-     * @return SearchEndpointInterface
-     *
      * @throws \RuntimeException Endpoint does not exist.
      */
-    public static function get($type)
+    public static function get(string $type): SearchEndpointInterface
     {
         if (!array_key_exists($type, self::$endpoints)) {
             throw new \RuntimeException('Endpoint does not exist.');
diff --git a/src/SearchEndpoint/SearchEndpointInterface.php b/src/SearchEndpoint/SearchEndpointInterface.php
index d0f4a0c7aa65bf4d3d84a21a1240594e6063ee0c..18cd114c8eadab4fa6d376d88700f73c1eca6511 100644
--- a/src/SearchEndpoint/SearchEndpointInterface.php
+++ b/src/SearchEndpoint/SearchEndpointInterface.php
@@ -24,11 +24,11 @@ interface SearchEndpointInterface extends NormalizableInterface
      * Adds builder to search endpoint.
      *
      * @param BuilderInterface $builder Builder to add.
-     * @param array $key Additional parameters relevant to builder.
+     * @param mixed $key Additional parameters relevant to builder.
      *
-     * @return string Key of added builder.
+     * @return mixed Key of added builder.
      */
-    public function add(BuilderInterface $builder, $key = null);
+    public function add(BuilderInterface $builder, mixed $key = null): mixed;
 
     /**
      * Adds builder to search endpoint's specific bool type container.
@@ -36,43 +36,31 @@ interface SearchEndpointInterface extends NormalizableInterface
      * @param BuilderInterface $builder Builder to add.
      * @param array $boolType Bool type for query or filter. If bool type is left null
      *                                       it will be treated as MUST.
-     * @param array $key Additional parameters relevant to builder.
+     * @param mixed $key Additional parameters relevant to builder.
      *
-     * @return string Key of added builder.
+     * @return mixed Key of added builder.
      */
-    public function addToBool(BuilderInterface $builder, ?string $boolType = null, mixed $key = null);
+    public function addToBool(BuilderInterface $builder, ?string $boolType = null, mixed $key = null): mixed;
 
     /**
      * Removes contained builder.
-     *
-     * @param int $key
-     *
-     * @return $this
      */
-    public function remove($key);
+    public function remove(mixed $key): static;
 
     /**
      * Returns contained builder or null if Builder is not found.
-     *
-     * @param int $key
-     *
-     * @return BuilderInterface|null
      */
-    public function get($key);
+    public function get(mixed $key): ?BuilderInterface;
 
     /**
      * Returns contained builder or null if Builder is not found.
      *
      * @param string|null $boolType If bool type is left null it will return all builders from container.
-     *
-     * @return array
      */
-    public function getAll($boolType = null);
+    public function getAll(?string $boolType = null): array;
 
     /**
      * Returns Bool filter or query instance with all builder objects inside.
-     *
-     * @return BoolQuery
      */
-    public function getBool();
+    public function getBool(): ?BoolQuery;
 }
diff --git a/tests/Functional/AbstractElasticsearchTestCase.php b/tests/Functional/AbstractElasticsearchTestCase.php
index 3df94835d2af1518497317531ab2d2636de9d796..a0ff7f252ba13bc7b296c73c9cace93311371025 100644
--- a/tests/Functional/AbstractElasticsearchTestCase.php
+++ b/tests/Functional/AbstractElasticsearchTestCase.php
@@ -54,7 +54,6 @@ abstract class AbstractElasticsearchTestCase extends TestCase
                 $bulkBody[] = [
                    'index' => [
                         '_index' => self::INDEX_NAME,
-                        '_type' => $type,
                         '_id' => $id,
                     ]
                 ];
@@ -119,22 +118,20 @@ abstract class AbstractElasticsearchTestCase extends TestCase
      * Execute search to the elasticsearch and handle results.
      *
      * @param Search $search Search object.
-     * @param null $type Types to search. Can be several types split by comma.
      * @param bool $returnRaw Return raw response from the client.
      * @return array
      */
-    protected function executeSearch(Search $search, $type = null, $returnRaw = false)
+    protected function executeSearch(Search $search, bool $returnRaw = false): array
     {
         $response = $this->client->search(
             array_filter([
                 'index' => self::INDEX_NAME,
-                'type' => $type,
                 'body' => $search->toArray(),
             ])
         );
 
         if ($returnRaw) {
-            return $response;
+            return $response->asArray();
         }
 
         $documents = [];
diff --git a/tests/Unit/Aggregation/Bucketing/DateHistogramAggregationTest.php b/tests/Unit/Aggregation/Bucketing/DateHistogramAggregationTest.php
index 0d4b55b5984a8a09359805fbacdd09fd74cf1380..af3d35b57d49cecfa6687fe9ce2aa57421e72388 100644
--- a/tests/Unit/Aggregation/Bucketing/DateHistogramAggregationTest.php
+++ b/tests/Unit/Aggregation/Bucketing/DateHistogramAggregationTest.php
@@ -40,6 +40,16 @@ class DateHistogramAggregationTest extends TestCase
         $this->assertEquals('date_histogram', $result);
     }
 
+    /**
+     * Tests if ChildrenAggregation#getArray throws exception when expected.
+     */
+    public function testGetArrayExceptionWhenDontSendInterval()
+    {
+        $this->expectException(\LogicException::class);
+        $aggregation = new DateHistogramAggregation('foo', 'date');
+        $aggregation->getArray();
+    }
+
     /**
      * Tests getArray method.
      */
@@ -51,10 +61,36 @@ class DateHistogramAggregationTest extends TestCase
         $aggregation = new DateHistogramAggregation('foo');
         $aggregation->addAggregation($mock);
         $aggregation->setField('date');
-        $aggregation->setInterval('month');
+        $aggregation->setCalendarInterval('month');
+
+        $result = $aggregation->getArray();
+        $expected = ['field' => 'date', 'calendar_interval' => 'month'];
+        $this->assertEquals($expected, $result);
+    }
+
+    /**
+     * Tests getArray method.
+     */
+    public function testCalendarIntervalGetArray()
+    {
+        $aggregation = new DateHistogramAggregation('foo');
+        $aggregation->setField('date');
+        $aggregation->setCalendarInterval('month');
+        $result = $aggregation->getArray();
+        $expected = ['field' => 'date', 'calendar_interval' => 'month'];
+        $this->assertEquals($expected, $result);
+    }
 
+    /**
+     * Tests getArray method.
+     */
+    public function testFixedIntervalGetArray()
+    {
+        $aggregation = new DateHistogramAggregation('foo');
+        $aggregation->setField('date');
+        $aggregation->setFixedInterval('month');
         $result = $aggregation->getArray();
-        $expected = ['field' => 'date', 'interval' => 'month'];
+        $expected = ['field' => 'date', 'fixed_interval' => 'month'];
         $this->assertEquals($expected, $result);
     }
 }
diff --git a/tests/Unit/Aggregation/Bucketing/FilterAggregationTest.php b/tests/Unit/Aggregation/Bucketing/FilterAggregationTest.php
index 89c1a93cd5bfe79e80d29b3a7c87f618d70b8cd5..0cc2f03b4a298ed940f872a56b8392b229439410 100644
--- a/tests/Unit/Aggregation/Bucketing/FilterAggregationTest.php
+++ b/tests/Unit/Aggregation/Bucketing/FilterAggregationTest.php
@@ -118,19 +118,37 @@ class FilterAggregationTest extends TestCase
         $this->expectException(\LogicException::class);
         $this->expectExceptionMessage('has no filter added');
         $aggregation = new FilterAggregation('test_agg');
-        $aggregation->toArray();
+        $result = $aggregation->toArray();
+        $this->assertEquals(
+            [
+                'aggregation' => [
+                    'test_agg' => [
+                        'filter' => []
+                    ]
+                ]
+            ],
+            $result
+        );
     }
 
     /**
      * Test for toArray() with setting a filter.
      */
-    #[DoesNotPerformAssertions]
     public function testToArrayWithFilter(): void
     {
         $aggregation = new FilterAggregation('test_agg');
-
         $aggregation->setFilter(new ExistsQuery('test'));
-        $aggregation->toArray();
+        $result = $aggregation->toArray();
+        $this->assertEquals(
+            [
+                'filter' => [
+                    'exists' => [
+                        'field' => 'test'
+                    ]
+                ]
+            ],
+            $result
+        );
     }
 
     /**
diff --git a/tests/Unit/Aggregation/Bucketing/HistogramAggregationTest.php b/tests/Unit/Aggregation/Bucketing/HistogramAggregationTest.php
new file mode 100644
index 0000000000000000000000000000000000000000..cdae5b4ec118f0132679471a7736fdd502c5fd70
--- /dev/null
+++ b/tests/Unit/Aggregation/Bucketing/HistogramAggregationTest.php
@@ -0,0 +1,112 @@
+<?php
+
+/*
+ * This file is part of the ONGR package.
+ *
+ * (c) NFQ Technologies UAB <info@nfq.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace ONGR\ElasticsearchDSL\Tests\Unit\Aggregation\Bucketing;
+
+use ONGR\ElasticsearchDSL\Aggregation\AbstractAggregation;
+use ONGR\ElasticsearchDSL\Aggregation\Bucketing\HistogramAggregation;
+use PHPUnit\Framework\TestCase;
+
+/**
+ * Unit test for children aggregation.
+ */
+class HistogramAggregationTest extends TestCase
+{
+    /**
+     * Tests if ChildrenAggregation#getArray throws exception when expected.
+     */
+    public function testGetArrayException()
+    {
+        $this->expectException(\LogicException::class);
+        $aggregation = new HistogramAggregation('foo');
+        $aggregation->getArray();
+    }
+
+    /**
+     * Tests if ChildrenAggregation#getArray throws exception when expected.
+     */
+    public function testGetArrayExceptionWhenDontSendInterval()
+    {
+        $this->expectException(\LogicException::class);
+        $aggregation = new HistogramAggregation('foo', 'age');
+        $aggregation->getArray();
+    }
+
+    /**
+     * Tests getType method.
+     */
+    public function testHistogramAggregationGetType()
+    {
+        $aggregation = new HistogramAggregation('foo');
+        $result = $aggregation->getType();
+        $this->assertEquals('histogram', $result);
+    }
+
+    /**
+     * Tests getArray method.
+     */
+    public function testChildrenAggregationGetArray()
+    {
+        $mock = $this->getMockBuilder(AbstractAggregation::class)
+            ->disableOriginalConstructor()
+            ->getMockForAbstractClass();
+        $aggregation = new HistogramAggregation('foo');
+        $aggregation->addAggregation($mock);
+        $aggregation->setField('age');
+        $aggregation->setInterval(10);
+        $result = $aggregation->getArray();
+        $expected = ['field' => 'age', 'interval' => 10];
+        $this->assertEquals($expected, $result);
+    }
+
+    /**
+     * Tests getArray method.
+     */
+    public function testIntervalGetArray()
+    {
+        $aggregation = new HistogramAggregation('foo');
+        $aggregation->setField('age');
+        $aggregation->setInterval(10);
+        $result = $aggregation->getArray();
+        $expected = ['field' => 'age', 'interval' => 10];
+        $this->assertEquals($expected, $result);
+    }
+
+    /**
+     * Tests getArray method.
+     */
+    public function testExtendedBoundsGetArray()
+    {
+        $aggregation = new HistogramAggregation('foo');
+        $aggregation->setField('age');
+        $aggregation->setInterval(10);
+        $aggregation->setExtendedBounds(0, 100);
+        $result = $aggregation->getArray();
+        $expected = ['field' => 'age', 'interval' => 10, 'extended_bounds' => ['min' => 0, 'max' => 100]];
+        $this->assertEquals(['min' => 0, 'max' => 100], $aggregation->getExtendedBounds());
+        $this->assertEquals($expected, $result);
+    }
+
+    /**
+     * Tests getArray method.
+     */
+    public function testExtendedBoundsWithNullGetArray()
+    {
+        $aggregation = new HistogramAggregation('foo');
+        $aggregation->setField('age');
+        $aggregation->setInterval(10);
+        $aggregation->setExtendedBounds(0, null);
+        $result = $aggregation->getArray();
+        $expected = ['field' => 'age', 'interval' => 10, 'extended_bounds' => ['min' => 0]];
+        $this->assertEquals(['min' => 0], $aggregation->getExtendedBounds());
+        $this->assertEquals($expected, $result);
+    }
+}
\ No newline at end of file
diff --git a/tests/Unit/Aggregation/Bucketing/TermsAggregationTest.php b/tests/Unit/Aggregation/Bucketing/TermsAggregationTest.php
index ecbb009ac35a49f923945f92754fdb93332fd646..b83fef2e3668a984966e1cb9976269cf96a0691b 100644
--- a/tests/Unit/Aggregation/Bucketing/TermsAggregationTest.php
+++ b/tests/Unit/Aggregation/Bucketing/TermsAggregationTest.php
@@ -179,12 +179,12 @@ class TermsAggregationTest extends TestCase
         // Case #7 terms aggregation with order term mode, desc direction.
         $aggregation = new TermsAggregation('test_agg');
         $aggregation->setField('test_field');
-        $aggregation->addParameter('order', ['_term' => 'desc']);
+        $aggregation->addParameter('order', ['_key' => 'desc']);
 
         $result = [
             'terms' => [
                 'field' => 'test_field',
-                'order' => ['_term' => 'desc'],
+                'order' => ['_key' => 'desc'],
             ],
         ];
 
diff --git a/tests/Unit/ParametersTraitTest.php b/tests/Unit/ParametersTraitTest.php
index d4035dc929abffb4704e8af9eba756396e802f08..8b58729a71432b3a9b82cc53910469e20c7551c8 100644
--- a/tests/Unit/ParametersTraitTest.php
+++ b/tests/Unit/ParametersTraitTest.php
@@ -39,8 +39,10 @@ class ParametersTraitTest extends TestCase
     public function testGetAndAddParameter(): void
     {
         $this->parametersTraitMock->addParameter('acme', 123);
+        $this->assertTrue(is_object($this->parametersTraitMock->addParameter('acme', 123)));
         $this->assertEquals(123, $this->parametersTraitMock->getParameter('acme'));
         $this->parametersTraitMock->addParameter('bar', 321);
         $this->assertEquals(321, $this->parametersTraitMock->getParameter('bar'));
+        $this->assertTrue(is_object($this->parametersTraitMock->removeParameter('acme')));
     }
 }
diff --git a/tests/Unit/Query/FullText/CommonTermsQueryTest.php b/tests/Unit/Query/FullText/CommonTermsQueryTest.php
deleted file mode 100644
index 05fd5dc4d7f0658d6b066bda3b939924a299296c..0000000000000000000000000000000000000000
--- a/tests/Unit/Query/FullText/CommonTermsQueryTest.php
+++ /dev/null
@@ -1,36 +0,0 @@
-<?php
-
-/*
- * This file is part of the ONGR package.
- *
- * (c) NFQ Technologies UAB <info@nfq.com>
- *
- * For the full copyright and license information, please view the LICENSE
- * file that was distributed with this source code.
- */
-
-namespace ONGR\ElasticsearchDSL\Tests\Unit\Query\FullText;
-
-use PHPUnit\Framework\TestCase;
-use ONGR\ElasticsearchDSL\Query\FullText\CommonTermsQuery;
-
-class CommonTermsQueryTest extends TestCase
-{
-    /**
-     * Tests toArray().
-     */
-    public function testToArray(): void
-    {
-        $query = new CommonTermsQuery('body', 'this is bonsai cool', ['cutoff_frequency' => 0.01]);
-        $expected = [
-            'common' => [
-                'body' => [
-                    'query' => 'this is bonsai cool',
-                    'cutoff_frequency' => 0.01,
-                ],
-            ],
-        ];
-
-        $this->assertEquals($expected, $query->toArray());
-    }
-}