diff --git a/composer.json b/composer.json
index 1f0b16f6a1ef83cc3df19652c64ef3153980b6f4..52d780430acf44601c6a415c931e249062b91b6b 100644
--- a/composer.json
+++ b/composer.json
@@ -32,7 +32,8 @@
     }
   },
   "require-dev": {
-    "phpunit/phpunit": "^9.5"
+    "phpunit/phpunit": "^9.5",
+    "symfony/var-dumper": "^6.3"
   },
   "scripts": {
     "tests": "php ./vendor/bin/phpunit --testdox --verbose"
diff --git a/src/ElasticSearch/Converter/CriteriaToEsRequest.php b/src/ElasticSearch/Converter/CriteriaToEsRequest.php
index c168286fdbcb111ab0c2f6e87ede3dcd7f6eeafb..94a7b9126a31baf60f435df89a1ef5a201cb4eaf 100644
--- a/src/ElasticSearch/Converter/CriteriaToEsRequest.php
+++ b/src/ElasticSearch/Converter/CriteriaToEsRequest.php
@@ -2,8 +2,20 @@
 
 namespace IQDEV\ElasticSearch\Converter;
 
-use IQDEV\ElasticSearch\Filter\PostFilterCollection;
-use IQDEV\ElasticSearch\Filter\QueryFilterCollection;
+use IQDEV\ElasticSearch\Criteria;
+use IQDEV\ElasticSearch\Document\Property\AttrType;
+use IQDEV\ElasticSearch\Document\Property\PropertyType;
+use IQDEV\ElasticSearch\Filter\Collection\FilterCollection;
+use IQDEV\ElasticSearch\Filter\Collection\FilterGroupCollection;
+use IQDEV\ElasticSearch\Filter\Collection\PostFilterCollection;
+use IQDEV\ElasticSearch\Filter\Collection\QueryFilterCollection;
+use IQDEV\ElasticSearch\Filter\Filter;
+use IQDEV\ElasticSearch\Filter\FilterOperator;
+use IQDEV\ElasticSearch\Filter\FilterType;
+use IQDEV\ElasticSearch\Filter\LogicOperator;
+use IQDEV\ElasticSearch\Filter\Value\FilterKeyword;
+use IQDEV\ElasticSearch\Filter\Value\FilterNumber;
+use IQDEV\ElasticSearch\Order\Order;
 use IQDEV\ElasticSearch\Order\OrderField;
 use IQDEV\ElasticSearch\Order\OrderKeywordProperty;
 use IQDEV\ElasticSearch\Order\OrderNumberProperty;
@@ -17,18 +29,6 @@ use IQDEV\ElasticSearch\Search\BoolQuery\Terms;
 use IQDEV\ElasticSearch\Search\Nested;
 use IQDEV\ElasticSearch\Search\Pagination;
 use IQDEV\ElasticSearch\Search\Request;
-use IQDEV\ElasticSearch\Criteria;
-use IQDEV\ElasticSearch\Document\Property\AttrType;
-use IQDEV\ElasticSearch\Document\Property\PropertyType;
-use IQDEV\ElasticSearch\Filter\Filter;
-use IQDEV\ElasticSearch\Filter\FilterCollection;
-use IQDEV\ElasticSearch\Filter\FilterGroupCollection;
-use IQDEV\ElasticSearch\Filter\FilterKeyword;
-use IQDEV\ElasticSearch\Filter\FilterNumber;
-use IQDEV\ElasticSearch\Filter\FilterOperator;
-use IQDEV\ElasticSearch\Filter\FilterType;
-use IQDEV\ElasticSearch\Filter\LogicOperator;
-use IQDEV\ElasticSearch\Order\Order;
 
 final class CriteriaToEsRequest
 {
@@ -62,18 +62,7 @@ final class CriteriaToEsRequest
 
         foreach ($criteria->sorting() as $order) {
             /** @var Order $order */
-
-            $direction = $order->orderType();
-
-            if ($order->orderBy() instanceof AttrType) {
-                $request->getSort()->add(new OrderField($order->orderBy(), $direction));
-            } elseif ($order->orderBy() instanceof PropertyType) {
-                if ($order->orderBy()->type() === PropertyType::TYPE_KEYWORD) {
-                    $request->getSort()->add(new OrderKeywordProperty($order->orderBy(), $direction));
-                } elseif ($order->orderBy()->type() === PropertyType::TYPE_NUMBER) {
-                    $request->getSort()->add(new OrderNumberProperty($order->orderBy(), $direction));
-                }
-            }
+            $request->getSort()->add($order);
         }
 
         return $request;
diff --git a/src/ElasticSearch/Converter/EsResponseToResult.php b/src/ElasticSearch/Converter/EsResponseToResult.php
index ee1262c7bd77e22f160ebdf392311598d8679e74..2b06234c95e885d6cb3196ca1b8bb3ec4f461504 100644
--- a/src/ElasticSearch/Converter/EsResponseToResult.php
+++ b/src/ElasticSearch/Converter/EsResponseToResult.php
@@ -4,12 +4,11 @@ namespace IQDEV\ElasticSearch\Converter;
 
 use Elastic\Elasticsearch\Response\Elasticsearch;
 use IQDEV\ElasticSearch\Document\Product;
-use IQDEV\ElasticSearch\Facet\Facet;
+use IQDEV\ElasticSearch\Facet\FacetType;
+use IQDEV\ElasticSearch\Facet\FacetResult;
 use IQDEV\ElasticSearch\Facet\Item\FacetItemList;
 use IQDEV\ElasticSearch\Facet\Item\FacetItemRange;
 use IQDEV\ElasticSearch\Facet\Item\FacetItemRangeDTO;
-use IQDEV\ElasticSearch\Facet\Type\FacetListType;
-use IQDEV\ElasticSearch\Facet\Type\FacetRangeType;
 use IQDEV\ElasticSearch\Result;
 
 final class EsResponseToResult
@@ -91,7 +90,7 @@ final class EsResponseToResult
             $code = $bucket['key'];
             $valueBucket = $bucket['agg_keyword_facet_value']['buckets'];
 
-            $facet = new Facet(new FacetListType(), $code);
+            $facet = new FacetResult(FacetType::LIST, $code);
 
             foreach ($valueBucket as $value) {
                 $count = 0;
@@ -127,9 +126,9 @@ final class EsResponseToResult
         foreach ($buckets as $bucket) {
             $code = $bucket['key'];
             $workBucket = $bucket['agg_number_facet_value'];
-            $selectedBuket = !empty($bucketsFiltered[$code]) ? $bucketsFiltered[$code] : null;
+            $selectedBucket = !empty($bucketsFiltered[$code]) ? $bucketsFiltered[$code] : null;
 
-            $facet = new Facet(new FacetRangeType(), $code);
+            $facet = new FacetResult(FacetType::RANGE, $code);
             $facetItem = FacetItemRange::create(
                 FacetItemRangeDTO::create(
                     $workBucket['min'],
@@ -137,14 +136,14 @@ final class EsResponseToResult
                     $workBucket['avg'],
                     $workBucket['sum']
                 ),
-                $selectedBuket !== null ? FacetItemRangeDTO::create(
-                    $selectedBuket['min'],
-                    $selectedBuket['max'],
-                    $selectedBuket['avg'],
-                    $selectedBuket['sum']
+                $selectedBucket !== null ? FacetItemRangeDTO::create(
+                    $selectedBucket['min'],
+                    $selectedBucket['max'],
+                    $selectedBucket['avg'],
+                    $selectedBucket['sum']
                 ) : FacetItemRangeDTO::create(),
-                $selectedBuket ? $selectedBuket['count'] : 0,
-                $selectedBuket !== null
+                $selectedBucket ? $selectedBucket['count'] : 0,
+                $selectedBucket !== null
             );
             $facet->products->add($facetItem);
 
diff --git a/src/ElasticSearch/Criteria.php b/src/ElasticSearch/Criteria.php
index 524d590d62eef17415e9cb4f6b20626869f25042..7b49d6a2a2d57c784dc76e70c065397d058df249 100644
--- a/src/ElasticSearch/Criteria.php
+++ b/src/ElasticSearch/Criteria.php
@@ -2,7 +2,7 @@
 
 namespace IQDEV\ElasticSearch;
 
-use IQDEV\ElasticSearch\Filter\FilterCollection;
+use IQDEV\ElasticSearch\Filter\Collection\FilterCollection;
 use IQDEV\ElasticSearch\Order\OrderCollection;
 
 final class Criteria
diff --git a/src/ElasticSearch/Document/ProductDocument.php b/src/ElasticSearch/Document/ProductDocument.php
index 87752e8f01f9320eaf03c4dca6651d4d412ef857..fefc014b97ed95ab5e61333f70b17c085c6f6aa7 100644
--- a/src/ElasticSearch/Document/ProductDocument.php
+++ b/src/ElasticSearch/Document/ProductDocument.php
@@ -4,8 +4,8 @@ namespace IQDEV\ElasticSearch\Document;
 
 use IQDEV\ElasticSearch\Config\MappingValidator;
 use IQDEV\ElasticSearch\Configuration;
-use IQDEV\ElasticSearch\Facet\FacetCategory;
-use IQDEV\ElasticSearch\Facet\FacetCollection;
+use IQDEV\ElasticSearch\Facet\Collection\FacetCollection;
+use IQDEV\ElasticSearch\Facet\Facet;
 use IQDEV\ElasticSearch\Helper\ArrayHelper;
 
 class ProductDocument implements Document
@@ -17,11 +17,11 @@ class ProductDocument implements Document
     private array $info = [];
     private bool $skipEmpty = false;
 
-    private FacetCategory $categoryFacet;
+    private Facet $categoryFacet;
 
 
     public function __construct(
-        FacetCategory $categoryFacet
+        Facet $categoryFacet
     )
     {
         $this->keywordFacets = new FacetCollection();
@@ -31,7 +31,7 @@ class ProductDocument implements Document
 
     }
 
-    public static function create(FacetCategory $categoryFacet): self
+    public static function create(Facet $categoryFacet): self
     {
         return new self($categoryFacet);
     }
@@ -45,9 +45,9 @@ class ProductDocument implements Document
     }
 
     /**
-     * @return FacetCategory
+     * @return Facet
      */
-    public function getCategoryFacet(): FacetCategory
+    public function getCategoryFacet(): Facet
     {
         return $this->categoryFacet;
     }
diff --git a/src/ElasticSearch/Document/Property/AttrType.php b/src/ElasticSearch/Document/Property/AttrType.php
deleted file mode 100644
index 246828dcb7f377c0fd583873d5a523d482b8591f..0000000000000000000000000000000000000000
--- a/src/ElasticSearch/Document/Property/AttrType.php
+++ /dev/null
@@ -1,30 +0,0 @@
-<?php
-
-namespace IQDEV\ElasticSearch\Document\Property;
-
-class AttrType implements Type
-{
-    protected string $key;
-    protected ?string $type;
-
-    public function __construct(string $key, ?string $type = null)
-    {
-        $this->key = $key;
-        $this->type = $type;
-    }
-
-    public function key(): string
-    {
-        return $this->key;
-    }
-
-    public function type(): ?string
-    {
-        return $this->type;
-    }
-
-    public static function types(): array
-    {
-        return [];
-    }
-}
\ No newline at end of file
diff --git a/src/ElasticSearch/Document/Property/Property.php b/src/ElasticSearch/Document/Property/Property.php
new file mode 100644
index 0000000000000000000000000000000000000000..79cfd35091a93b4db8fe3046ae45dbf56def5c6d
--- /dev/null
+++ b/src/ElasticSearch/Document/Property/Property.php
@@ -0,0 +1,22 @@
+<?php
+
+namespace IQDEV\ElasticSearch\Document\Property;
+
+class Property
+{
+    public function __construct(
+        protected string $key,
+        protected PropertyType $type = PropertyType::BASE,
+    ) {
+    }
+
+    public function getKey(): string
+    {
+        return $this->key;
+    }
+
+    public function getType(): PropertyType
+    {
+        return $this->type;
+    }
+}
diff --git a/src/ElasticSearch/Document/Property/PropertyType.php b/src/ElasticSearch/Document/Property/PropertyType.php
index f533c516955c1aeec88d718fdb54486da2636d38..17476b37966608f4fca409527eef920bea71bb43 100644
--- a/src/ElasticSearch/Document/Property/PropertyType.php
+++ b/src/ElasticSearch/Document/Property/PropertyType.php
@@ -2,39 +2,9 @@
 
 namespace IQDEV\ElasticSearch\Document\Property;
 
-class PropertyType implements Type
+enum PropertyType
 {
-    protected string $key;
-    protected string $type;
-
-    public const TYPE_NUMBER = 'number';
-    public const TYPE_KEYWORD = 'keyword';
-
-    public function __construct(string $key, string $type = null)
-    {
-        if (!in_array($type, self::types(), true)) {
-            throw new \InvalidArgumentException(sprintf('Invalid type "%s" for property "%s"', $type, $key));
-        }
-
-        $this->key = $key;
-        $this->type = $type;
-    }
-
-    public function key(): string
-    {
-        return $this->key;
-    }
-
-    public function type(): string
-    {
-        return $this->type;
-    }
-
-    public static function types(): array
-    {
-        return [
-            self::TYPE_NUMBER,
-            self::TYPE_KEYWORD,
-        ];
-    }
+    case BASE;
+    case KEYWORD;
+    case NUMBER;
 }
diff --git a/src/ElasticSearch/Document/Property/Type.php b/src/ElasticSearch/Document/Property/Type.php
deleted file mode 100644
index 94699448123d2e09e9242ff1f44ca406e95a1700..0000000000000000000000000000000000000000
--- a/src/ElasticSearch/Document/Property/Type.php
+++ /dev/null
@@ -1,13 +0,0 @@
-<?php
-
-namespace IQDEV\ElasticSearch\Document\Property;
-
-interface Type
-{
-    public function key(): string;
-
-    public function type(): ?string;
-
-    /** @return string[] */
-    public static function types(): array;
-}
diff --git a/src/ElasticSearch/Facet/FacetCollection.php b/src/ElasticSearch/Facet/Collection/FacetCollection.php
similarity index 80%
rename from src/ElasticSearch/Facet/FacetCollection.php
rename to src/ElasticSearch/Facet/Collection/FacetCollection.php
index d628b75fbd8de60ec0f8fd7f25717af174e811c1..a257b3a50ca38875a60b934dba1915ccd8eaa8bf 100644
--- a/src/ElasticSearch/Facet/FacetCollection.php
+++ b/src/ElasticSearch/Facet/Collection/FacetCollection.php
@@ -1,8 +1,9 @@
 <?php
 
-namespace IQDEV\ElasticSearch\Facet;
+namespace IQDEV\ElasticSearch\Facet\Collection;
 
 use IQDEV\ElasticSearch\Esable;
+use IQDEV\ElasticSearch\Facet\Facetable;
 use Ramsey\Collection\AbstractCollection;
 
 final class FacetCollection extends AbstractCollection implements Esable
diff --git a/src/ElasticSearch/Facet/Collection/FacetResultCollection.php b/src/ElasticSearch/Facet/Collection/FacetResultCollection.php
new file mode 100644
index 0000000000000000000000000000000000000000..3d51f0d228ed441f33c89ff1092c16529a043056
--- /dev/null
+++ b/src/ElasticSearch/Facet/Collection/FacetResultCollection.php
@@ -0,0 +1,18 @@
+<?php
+
+namespace IQDEV\ElasticSearch\Facet\Collection;
+
+use IQDEV\ElasticSearch\Facet\FacetResult;
+use Ramsey\Collection\AbstractCollection;
+
+final class FacetResultCollection extends AbstractCollection
+{
+
+    /**
+     * @inheritDoc
+     */
+    public function getType(): string
+    {
+        return FacetResult::class;
+    }
+}
diff --git a/src/ElasticSearch/Facet/Facet.php b/src/ElasticSearch/Facet/Facet.php
index a0f02281360b845341ec7aa55215d08116181a0f..ecfee8f216a09d57d3e7b51a6dea9d568d5fbe70 100644
--- a/src/ElasticSearch/Facet/Facet.php
+++ b/src/ElasticSearch/Facet/Facet.php
@@ -2,39 +2,18 @@
 
 namespace IQDEV\ElasticSearch\Facet;
 
-use IQDEV\ElasticSearch\Facet\Item\FacetItemCollection;
-use IQDEV\ElasticSearch\Facet\Type\FacetType;
+use IQDEV\ElasticSearch\Document\Property\Property;
 
-class Facet implements Facetable
+abstract class Facet implements Facetable
 {
-    public FacetItemCollection $products;
-
-    protected FacetType $type;
-
-    protected string $code;
-
-    public function __construct(FacetType $type, string $code)
-    {
-        $this->type = $type;
-        $this->code = $code;
-        $this->products = new FacetItemCollection();
-    }
-
-    public function getType(): FacetType
-    {
-        return $this->type;
-    }
-
-    public function getCode(): string
-    {
-        return $this->code;
+    public function __construct(
+        protected Property $property,
+        protected mixed $value,
+    ) {
     }
 
-    public function es(): array
+    public function getProperty(): Property
     {
-        return [
-            'facet_code' => $this->code,
-            'facet_value' => $this->type,
-        ];
+        return $this->property;
     }
 }
diff --git a/src/ElasticSearch/Facet/FacetCategory.php b/src/ElasticSearch/Facet/FacetCategory.php
deleted file mode 100644
index 6e286b1c37f56d3788ac89eae4a45cd76b481d3b..0000000000000000000000000000000000000000
--- a/src/ElasticSearch/Facet/FacetCategory.php
+++ /dev/null
@@ -1,22 +0,0 @@
-<?php
-
-namespace IQDEV\ElasticSearch\Facet;
-
-use IQDEV\ElasticSearch\Esable;
-
-final class FacetCategory implements Esable
-{
-    private string $category;
-
-    public function __construct(string $category)
-    {
-        $this->category = $category;
-    }
-
-    public function es(): array
-    {
-        return [
-            'category_id' => $this->category,
-        ];
-    }
-}
diff --git a/src/ElasticSearch/Facet/FacetFactory.php b/src/ElasticSearch/Facet/FacetFactory.php
new file mode 100644
index 0000000000000000000000000000000000000000..005083779976c9aa17aad0f9681d7a0320c90610
--- /dev/null
+++ b/src/ElasticSearch/Facet/FacetFactory.php
@@ -0,0 +1,23 @@
+<?php
+
+namespace IQDEV\ElasticSearch\Facet;
+
+use IQDEV\ElasticSearch\Document\Property\Property;
+use IQDEV\ElasticSearch\Document\Property\PropertyType;
+use IQDEV\ElasticSearch\Facet\Type\BaseFacet;
+use IQDEV\ElasticSearch\Facet\Type\KeywordFacet;
+use IQDEV\ElasticSearch\Facet\Type\NumberFacet;
+
+class FacetFactory
+{
+    public static function createFromProperty(Property $property, mixed $value): Facet
+    {
+        match ($property->getType()) {
+            PropertyType::KEYWORD => $facet = new KeywordFacet($property, $value),
+            PropertyType::NUMBER => $facet = new NumberFacet($property, $value),
+            default => $facet = new BaseFacet($property, $value),
+        };
+
+        return $facet;
+    }
+}
diff --git a/src/ElasticSearch/Facet/FacetKeyword.php b/src/ElasticSearch/Facet/FacetKeyword.php
deleted file mode 100644
index 11fd094ba55b78bf25dbd61fbf2a03983299d20f..0000000000000000000000000000000000000000
--- a/src/ElasticSearch/Facet/FacetKeyword.php
+++ /dev/null
@@ -1,27 +0,0 @@
-<?php
-
-namespace IQDEV\ElasticSearch\Facet;
-
-final class FacetKeyword implements Facetable
-{
-    private string $key;
-    /** @var string|array<string> */
-    private string|array $value;
-
-    /**
-     * @param string|string[] $value
-     */
-    public function __construct(string $key, string|array $value)
-    {
-        $this->key = $key;
-        $this->value = $value;
-    }
-
-    public function es(): array
-    {
-        return [
-            'facet_code' => $this->key,
-            'facet_value' => $this->value,
-        ];
-    }
-}
diff --git a/src/ElasticSearch/Facet/FacetNumber.php b/src/ElasticSearch/Facet/FacetNumber.php
deleted file mode 100644
index 12bf9837ae1959d3f353c8d01ad7f3b665d3c496..0000000000000000000000000000000000000000
--- a/src/ElasticSearch/Facet/FacetNumber.php
+++ /dev/null
@@ -1,23 +0,0 @@
-<?php
-
-namespace IQDEV\ElasticSearch\Facet;
-
-final class FacetNumber implements Facetable
-{
-    private string $key;
-    private float $value;
-
-    public function __construct(string $key, float $value)
-    {
-        $this->key = $key;
-        $this->value = $value;
-    }
-
-    public function es(): array
-    {
-        return [
-            'facet_code' => $this->key,
-            'facet_value' => $this->value,
-        ];
-    }
-}
diff --git a/src/ElasticSearch/Facet/FacetResult.php b/src/ElasticSearch/Facet/FacetResult.php
new file mode 100644
index 0000000000000000000000000000000000000000..66c608f3477ab3b09082c74f49ac8c9646e760e9
--- /dev/null
+++ b/src/ElasticSearch/Facet/FacetResult.php
@@ -0,0 +1,31 @@
+<?php
+
+namespace IQDEV\ElasticSearch\Facet;
+
+use IQDEV\ElasticSearch\Facet\Item\FacetItemCollection;
+
+class FacetResult
+{
+    public FacetItemCollection $products;
+
+    protected FacetType $type;
+
+    protected string $code;
+
+    public function __construct(FacetType $type, string $code)
+    {
+        $this->type = $type;
+        $this->code = $code;
+        $this->products = new FacetItemCollection();
+    }
+
+    public function getType(): FacetType
+    {
+        return $this->type;
+    }
+
+    public function getCode(): string
+    {
+        return $this->code;
+    }
+}
diff --git a/src/ElasticSearch/Facet/FacetType.php b/src/ElasticSearch/Facet/FacetType.php
new file mode 100644
index 0000000000000000000000000000000000000000..9a8f9dd0b5cf39125b6805a7165259a05950e1ef
--- /dev/null
+++ b/src/ElasticSearch/Facet/FacetType.php
@@ -0,0 +1,9 @@
+<?php
+
+namespace IQDEV\ElasticSearch\Facet;
+
+enum FacetType: string
+{
+    case LIST = 'list';
+    case RANGE = 'range';
+}
diff --git a/src/ElasticSearch/Facet/FacetTypeEnum.php b/src/ElasticSearch/Facet/FacetTypeEnum.php
deleted file mode 100644
index e0491c7094168e28eb5b878ba87492a7b41b1151..0000000000000000000000000000000000000000
--- a/src/ElasticSearch/Facet/FacetTypeEnum.php
+++ /dev/null
@@ -1,9 +0,0 @@
-<?php
-
-namespace IQDEV\ElasticSearch\Facet;
-
-enum FacetTypeEnum: string
-{
-    case KEYWORD = 'keyword';
-    case NUMBER = 'number';
-}
diff --git a/src/ElasticSearch/Facet/NewFacet.php b/src/ElasticSearch/Facet/NewFacet.php
deleted file mode 100644
index cc08955f35224bcff56fe9b4f35a4f5fae6f3fae..0000000000000000000000000000000000000000
--- a/src/ElasticSearch/Facet/NewFacet.php
+++ /dev/null
@@ -1,15 +0,0 @@
-<?php
-
-declare(strict_types=1);
-
-namespace IQDEV\ElasticSearch\Facet;
-
-class NewFacet implements Facetable
-{
-    protected FacetTypeEnum $type;
-
-    public function es(): array
-    {
-        return [];
-    }
-}
diff --git a/src/ElasticSearch/Facet/Type/BaseFacet.php b/src/ElasticSearch/Facet/Type/BaseFacet.php
new file mode 100644
index 0000000000000000000000000000000000000000..690f0ed8a10be3c820404e2709348829ad9e8bfa
--- /dev/null
+++ b/src/ElasticSearch/Facet/Type/BaseFacet.php
@@ -0,0 +1,18 @@
+<?php
+
+namespace IQDEV\ElasticSearch\Facet\Type;
+
+use IQDEV\ElasticSearch\Facet\Facet;
+
+final class BaseFacet extends Facet
+{
+    /**
+     * @inheritDoc
+     */
+    public function es(): array
+    {
+        return [
+            $this->property->getKey() => $this->value,
+        ];
+    }
+}
diff --git a/src/ElasticSearch/Facet/Type/FacetListType.php b/src/ElasticSearch/Facet/Type/FacetListType.php
deleted file mode 100644
index fc393aac5d1f35683afe899b5ff6a53b80db3350..0000000000000000000000000000000000000000
--- a/src/ElasticSearch/Facet/Type/FacetListType.php
+++ /dev/null
@@ -1,7 +0,0 @@
-<?php
-
-namespace IQDEV\ElasticSearch\Facet\Type;
-
-class FacetListType implements FacetType
-{
-}
\ No newline at end of file
diff --git a/src/ElasticSearch/Facet/Type/FacetRangeType.php b/src/ElasticSearch/Facet/Type/FacetRangeType.php
deleted file mode 100644
index 344e2c8be2d0447fcc6f3992349cd15f4be748c3..0000000000000000000000000000000000000000
--- a/src/ElasticSearch/Facet/Type/FacetRangeType.php
+++ /dev/null
@@ -1,7 +0,0 @@
-<?php
-
-namespace IQDEV\ElasticSearch\Facet\Type;
-
-class FacetRangeType implements FacetType
-{
-}
diff --git a/src/ElasticSearch/Facet/Type/FacetType.php b/src/ElasticSearch/Facet/Type/FacetType.php
deleted file mode 100644
index 5ec289c2ae8dd34a30143157d6efb294b00a42e4..0000000000000000000000000000000000000000
--- a/src/ElasticSearch/Facet/Type/FacetType.php
+++ /dev/null
@@ -1,7 +0,0 @@
-<?php
-
-namespace IQDEV\ElasticSearch\Facet\Type;
-
-interface FacetType
-{
-}
diff --git a/src/ElasticSearch/Facet/Type/KeywordFacet.php b/src/ElasticSearch/Facet/Type/KeywordFacet.php
new file mode 100644
index 0000000000000000000000000000000000000000..ffc1aacab801ce376f4c9a3e8d459c9775d1a87f
--- /dev/null
+++ b/src/ElasticSearch/Facet/Type/KeywordFacet.php
@@ -0,0 +1,19 @@
+<?php
+
+namespace IQDEV\ElasticSearch\Facet\Type;
+
+use IQDEV\ElasticSearch\Facet\Facet;
+
+final class KeywordFacet extends Facet
+{
+    /**
+     * @inheritDoc
+     */
+    public function es(): array
+    {
+        return [
+            'facet_code' => $this->property->getKey(),
+            'facet_value' => (string) $this->value,
+        ];
+    }
+}
diff --git a/src/ElasticSearch/Facet/Type/NumberFacet.php b/src/ElasticSearch/Facet/Type/NumberFacet.php
new file mode 100644
index 0000000000000000000000000000000000000000..43e4c8e5e27f087fe348754328334e0ad60496b0
--- /dev/null
+++ b/src/ElasticSearch/Facet/Type/NumberFacet.php
@@ -0,0 +1,19 @@
+<?php
+
+namespace IQDEV\ElasticSearch\Facet\Type;
+
+use IQDEV\ElasticSearch\Facet\Facet;
+
+final class NumberFacet extends Facet
+{
+    /**
+     * @inheritDoc
+     */
+    public function es(): array
+    {
+        return [
+            'facet_code' => $this->property->getKey(),
+            'facet_value' => (float) $this->value,
+        ];
+    }
+}
diff --git a/src/ElasticSearch/Filter/FilterCollection.php b/src/ElasticSearch/Filter/Collection/FilterCollection.php
similarity index 92%
rename from src/ElasticSearch/Filter/FilterCollection.php
rename to src/ElasticSearch/Filter/Collection/FilterCollection.php
index 7bb1d492d17be4d1237ff7add4375a0c7f1a38b6..69fc460144c04b29bbbd36bb818628e4a25efb26 100644
--- a/src/ElasticSearch/Filter/FilterCollection.php
+++ b/src/ElasticSearch/Filter/Collection/FilterCollection.php
@@ -1,7 +1,8 @@
 <?php
 
-namespace IQDEV\ElasticSearch\Filter;
+namespace IQDEV\ElasticSearch\Filter\Collection;
 
+use IQDEV\ElasticSearch\Filter\LogicOperator;
 use Ramsey\Collection\AbstractCollection;
 
 /**
diff --git a/src/ElasticSearch/Filter/FilterGroupCollection.php b/src/ElasticSearch/Filter/Collection/FilterGroupCollection.php
similarity index 90%
rename from src/ElasticSearch/Filter/FilterGroupCollection.php
rename to src/ElasticSearch/Filter/Collection/FilterGroupCollection.php
index 5bbce1e00950694da132e90ca872776b617aeff2..9f6c8ada0469343c9ab594b7875be966f586e319 100644
--- a/src/ElasticSearch/Filter/FilterGroupCollection.php
+++ b/src/ElasticSearch/Filter/Collection/FilterGroupCollection.php
@@ -1,7 +1,10 @@
 <?php
 
-namespace IQDEV\ElasticSearch\Filter;
+namespace IQDEV\ElasticSearch\Filter\Collection;
 
+use IQDEV\ElasticSearch\Filter\Filter;
+use IQDEV\ElasticSearch\Filter\FilterType;
+use IQDEV\ElasticSearch\Filter\LogicOperator;
 use Ramsey\Collection\AbstractCollection;
 
 /**
diff --git a/src/ElasticSearch/Filter/PostFilterCollection.php b/src/ElasticSearch/Filter/Collection/PostFilterCollection.php
similarity index 56%
rename from src/ElasticSearch/Filter/PostFilterCollection.php
rename to src/ElasticSearch/Filter/Collection/PostFilterCollection.php
index 8b677a747f11cfb0b6839c3eac6100fabfaa657b..482c5d5e7ef64d7eb6844d842b7981b2ba6862eb 100644
--- a/src/ElasticSearch/Filter/PostFilterCollection.php
+++ b/src/ElasticSearch/Filter/Collection/PostFilterCollection.php
@@ -1,6 +1,6 @@
 <?php
 
-namespace IQDEV\ElasticSearch\Filter;
+namespace IQDEV\ElasticSearch\Filter\Collection;
 
 class PostFilterCollection extends FilterCollection
 {
diff --git a/src/ElasticSearch/Filter/QueryFilterCollection.php b/src/ElasticSearch/Filter/Collection/QueryFilterCollection.php
similarity index 56%
rename from src/ElasticSearch/Filter/QueryFilterCollection.php
rename to src/ElasticSearch/Filter/Collection/QueryFilterCollection.php
index aa700cca6b46ede7f23f2aba07efc2c43c9f2ccc..96258d25b014cd656087a577d3ef71ff80d9c4d4 100644
--- a/src/ElasticSearch/Filter/QueryFilterCollection.php
+++ b/src/ElasticSearch/Filter/Collection/QueryFilterCollection.php
@@ -1,6 +1,6 @@
 <?php
 
-namespace IQDEV\ElasticSearch\Filter;
+namespace IQDEV\ElasticSearch\Filter\Collection;
 
 class QueryFilterCollection extends FilterCollection
 {
diff --git a/src/ElasticSearch/Filter/FilterKeyword.php b/src/ElasticSearch/Filter/Value/FilterKeyword.php
similarity index 80%
rename from src/ElasticSearch/Filter/FilterKeyword.php
rename to src/ElasticSearch/Filter/Value/FilterKeyword.php
index d3edd61bbb6bd3abd33eb81a98cb97dcb569eef0..90c83b566764e654c066207c9f2c4a45a94141cf 100644
--- a/src/ElasticSearch/Filter/FilterKeyword.php
+++ b/src/ElasticSearch/Filter/Value/FilterKeyword.php
@@ -1,6 +1,8 @@
 <?php
 
-namespace IQDEV\ElasticSearch\Filter;
+namespace IQDEV\ElasticSearch\Filter\Value;
+
+use IQDEV\ElasticSearch\Filter\FilterValue;
 
 class FilterKeyword implements FilterValue
 {
diff --git a/src/ElasticSearch/Filter/FilterNumber.php b/src/ElasticSearch/Filter/Value/FilterNumber.php
similarity index 77%
rename from src/ElasticSearch/Filter/FilterNumber.php
rename to src/ElasticSearch/Filter/Value/FilterNumber.php
index 7a9dc755eb7f8c77fe95ebb89fa3b916de1ed61e..d793ea69599d646e3cb12ce86505ac0333972569 100644
--- a/src/ElasticSearch/Filter/FilterNumber.php
+++ b/src/ElasticSearch/Filter/Value/FilterNumber.php
@@ -1,6 +1,8 @@
 <?php
 
-namespace IQDEV\ElasticSearch\Filter;
+namespace IQDEV\ElasticSearch\Filter\Value;
+
+use IQDEV\ElasticSearch\Filter\FilterValue;
 
 class FilterNumber implements FilterValue
 {
diff --git a/src/ElasticSearch/Indexer/BaseIndexProvider.php b/src/ElasticSearch/Indexer/BaseIndexProvider.php
index 83df733641c89b3cb155a9a053eeb064202e0a66..dcce508f241e6a3cebf9be32c09ac0ffceacc56c 100644
--- a/src/ElasticSearch/Indexer/BaseIndexProvider.php
+++ b/src/ElasticSearch/Indexer/BaseIndexProvider.php
@@ -4,8 +4,9 @@ namespace IQDEV\ElasticSearch\Indexer;
 
 use IQDEV\ElasticSearch\Configuration;
 use IQDEV\ElasticSearch\Document\ProductDocument;
-use IQDEV\ElasticSearch\Facet\FacetCategory;
-use IQDEV\ElasticSearch\Facet\FacetKeyword;
+use IQDEV\ElasticSearch\Document\Property\Property;
+use IQDEV\ElasticSearch\Document\Property\PropertyType;
+use IQDEV\ElasticSearch\Facet\FacetFactory;
 
 class BaseIndexProvider implements IndexProvider
 {
@@ -23,14 +24,21 @@ class BaseIndexProvider implements IndexProvider
     public function get(): \Generator
     {
         foreach ($this->products as $product) {
-            $document = new ProductDocument(new FacetCategory($product['category']));
+            $document = new ProductDocument(
+                FacetFactory::createFromProperty(new Property('category_id', PropertyType::BASE), $product['category'])
+            );
+
             $document->setAdditionData($product['data'] ?? []);
             foreach ($product['properties'] as $type => $values) {
-                foreach ($values as $key => $prop) {
+                foreach ($values as $key => $value) {
                     if ($type === 'number') {
-                        $document->getNumberFacets()->add(new FacetKeyword($key, $prop));
+                        $document->getNumberFacets()->add(
+                            FacetFactory::createFromProperty(new Property($key, PropertyType::NUMBER), $value)
+                        );
                     } else {
-                        $document->getKeywordFacets()->add(new FacetKeyword($key, $prop));
+                        $document->getKeywordFacets()->add(
+                            FacetFactory::createFromProperty(new Property($key, PropertyType::KEYWORD), $value)
+                        );
                     }
                 }
             }
diff --git a/src/ElasticSearch/Order/Order.php b/src/ElasticSearch/Order/Order.php
index 82d4ac81b6b2f8888f7f26fe1af6fc56845c351a..056001117ad498fc82ed4ea2c82d7b5723a2e719 100644
--- a/src/ElasticSearch/Order/Order.php
+++ b/src/ElasticSearch/Order/Order.php
@@ -2,39 +2,30 @@
 
 namespace IQDEV\ElasticSearch\Order;
 
+use IQDEV\ElasticSearch\Document\Property\Property;
 use IQDEV\ElasticSearch\Esable;
-use IQDEV\ElasticSearch\Document\Property\Type;
 
-class Order implements Esable
+abstract class Order implements Esable
 {
-    public Type $by;
-    public OrderType $direction;
-    public array $properties;
-
-    public function __construct(Type $by, OrderType $direction, array $properties = [])
-    {
-        $this->by = $by;
-        $this->direction = $direction;
-        $this->properties = $properties;
-    }
-
-    public function es(): array
-    {
-        return array_merge([$this->by->key() => $this->direction::getType()], $this->properties);
+    public function __construct(
+        protected Property $property,
+        protected OrderDirection $direction,
+        protected array $additionalParams = [],
+    ) {
     }
 
-    public function orderBy(): Type
+    public function getProperty(): Property
     {
-        return $this->by;
+        return $this->property;
     }
 
-    public function orderType(): OrderType
+    public function getDirection(): OrderDirection
     {
         return $this->direction;
     }
 
-    public function orderProperties(): array
+    public function getAdditionalParams(): array
     {
-        return $this->properties;
+        return $this->additionalParams;
     }
 }
diff --git a/src/ElasticSearch/Order/OrderAscType.php b/src/ElasticSearch/Order/OrderAscType.php
deleted file mode 100644
index 69b8f08ae438dd256953c7da4a322cdbf718795c..0000000000000000000000000000000000000000
--- a/src/ElasticSearch/Order/OrderAscType.php
+++ /dev/null
@@ -1,8 +0,0 @@
-<?php
-
-namespace IQDEV\ElasticSearch\Order;
-
-class OrderAscType extends OrderType
-{
-    protected static string $code = 'asc';
-}
diff --git a/src/ElasticSearch/Order/OrderDescType.php b/src/ElasticSearch/Order/OrderDescType.php
deleted file mode 100644
index 775fa3c195ec75b01a7a5d0102309f5bca0518f7..0000000000000000000000000000000000000000
--- a/src/ElasticSearch/Order/OrderDescType.php
+++ /dev/null
@@ -1,8 +0,0 @@
-<?php
-
-namespace IQDEV\ElasticSearch\Order;
-
-class OrderDescType extends OrderType
-{
-    protected static string $code = 'desc';
-}
diff --git a/src/ElasticSearch/Order/OrderDirection.php b/src/ElasticSearch/Order/OrderDirection.php
new file mode 100644
index 0000000000000000000000000000000000000000..a5f4b754aae8fdb2b790c34b5ef05edf7c6c94c7
--- /dev/null
+++ b/src/ElasticSearch/Order/OrderDirection.php
@@ -0,0 +1,9 @@
+<?php
+
+namespace IQDEV\ElasticSearch\Order;
+
+enum OrderDirection: string
+{
+    case ASC = 'asc';
+    case DESC = 'desc';
+}
diff --git a/src/ElasticSearch/Order/OrderFactory.php b/src/ElasticSearch/Order/OrderFactory.php
new file mode 100644
index 0000000000000000000000000000000000000000..5764491b2337340fa904a179a650771f56b45aea
--- /dev/null
+++ b/src/ElasticSearch/Order/OrderFactory.php
@@ -0,0 +1,25 @@
+<?php
+
+namespace IQDEV\ElasticSearch\Order;
+
+use IQDEV\ElasticSearch\Document\Property\Property;
+use IQDEV\ElasticSearch\Document\Property\PropertyType;
+use IQDEV\ElasticSearch\Order\Type\BaseOrder;
+use IQDEV\ElasticSearch\Order\Type\KeywordPropertyOrder;
+use IQDEV\ElasticSearch\Order\Type\NumberPropertyOrder;
+
+class OrderFactory
+{
+    public static function createByProperty(
+        Property $property,
+        OrderDirection $direction,
+    ): Order {
+        match ($property->getType()) {
+            PropertyType::KEYWORD => $order = new KeywordPropertyOrder($property, $direction),
+            PropertyType::NUMBER => $order = new NumberPropertyOrder($property, $direction),
+            default => $order = new BaseOrder($property, $direction),
+        };
+
+        return $order;
+    }
+}
diff --git a/src/ElasticSearch/Order/OrderField.php b/src/ElasticSearch/Order/OrderField.php
deleted file mode 100644
index ba566509642ad09dcc5d3339422fc97714f05f32..0000000000000000000000000000000000000000
--- a/src/ElasticSearch/Order/OrderField.php
+++ /dev/null
@@ -1,7 +0,0 @@
-<?php
-
-namespace IQDEV\ElasticSearch\Order;
-
-class OrderField extends Order
-{
-}
diff --git a/src/ElasticSearch/Order/OrderType.php b/src/ElasticSearch/Order/OrderType.php
deleted file mode 100644
index 979e079512986db62acecab02ab56a320e6c1524..0000000000000000000000000000000000000000
--- a/src/ElasticSearch/Order/OrderType.php
+++ /dev/null
@@ -1,13 +0,0 @@
-<?php
-
-namespace IQDEV\ElasticSearch\Order;
-
-abstract class OrderType
-{
-    protected static string $code;
-
-    public static function getType(): string
-    {
-        return static::$code;
-    }
-}
diff --git a/src/ElasticSearch/Order/Type/BaseOrder.php b/src/ElasticSearch/Order/Type/BaseOrder.php
new file mode 100644
index 0000000000000000000000000000000000000000..3af241721ba5de879c9a4a286b6acd5da2f2a3e1
--- /dev/null
+++ b/src/ElasticSearch/Order/Type/BaseOrder.php
@@ -0,0 +1,16 @@
+<?php
+
+namespace IQDEV\ElasticSearch\Order\Type;
+
+use IQDEV\ElasticSearch\Order\Order;
+
+class BaseOrder extends Order
+{
+    public function es(): array
+    {
+        return array_merge(
+            [$this->property->getKey() => $this->direction->value],
+            $this->additionalParams
+        );
+    }
+}
diff --git a/src/ElasticSearch/Order/OrderKeywordProperty.php b/src/ElasticSearch/Order/Type/KeywordPropertyOrder.php
similarity index 54%
rename from src/ElasticSearch/Order/OrderKeywordProperty.php
rename to src/ElasticSearch/Order/Type/KeywordPropertyOrder.php
index f0ae3e1d6278a59770e189a8c61d702223c446de..eee8fe5f6f4033c3e0b1d893a2290baee7dee71c 100644
--- a/src/ElasticSearch/Order/OrderKeywordProperty.php
+++ b/src/ElasticSearch/Order/Type/KeywordPropertyOrder.php
@@ -1,29 +1,34 @@
 <?php
 
-namespace IQDEV\ElasticSearch\Order;
+namespace IQDEV\ElasticSearch\Order\Type;
 
-class OrderKeywordProperty extends Order
+use IQDEV\ElasticSearch\Order\Order;
+
+class KeywordPropertyOrder extends Order
 {
     public function es(): array
     {
         $order = [
-            'order' => $this->direction::getType(),
+            'order' => $this->direction->value,
             'nested' => [
                 'path' => 'search_data',
                 'filter' => [
                     'bool' => [
                         'must' => [
                             'term' => [
-                                'search_data.keyword_facet.facet_code' => $this->by->key(),
-                            ]
+                                'search_data.keyword_facet.facet_code' => $this->property->getKey(),
+                            ],
                         ],
                     ],
                 ],
             ],
         ];
-        $order = array_merge($order, $this->properties);
+
         return [
-            'search_data.keyword_facet.facet_value' => $order,
+            'search_data.keyword_facet.facet_value' => array_merge(
+                $order,
+                $this->additionalParams
+            ),
         ];
     }
 }
diff --git a/src/ElasticSearch/Order/OrderNumberProperty.php b/src/ElasticSearch/Order/Type/NumberPropertyOrder.php
similarity index 55%
rename from src/ElasticSearch/Order/OrderNumberProperty.php
rename to src/ElasticSearch/Order/Type/NumberPropertyOrder.php
index b6a14016e218c29eb2dcb3f9b5d1df5c92679037..6a918a46db73e736e55994a8d9bcbae2768c50ba 100644
--- a/src/ElasticSearch/Order/OrderNumberProperty.php
+++ b/src/ElasticSearch/Order/Type/NumberPropertyOrder.php
@@ -1,29 +1,34 @@
 <?php
 
-namespace IQDEV\ElasticSearch\Order;
+namespace IQDEV\ElasticSearch\Order\Type;
 
-class OrderNumberProperty extends Order
+use IQDEV\ElasticSearch\Order\Order;
+
+class NumberPropertyOrder extends Order
 {
     public function es(): array
     {
         $order = [
-            'order' => $this->direction::getType(),
+            'order' => $this->direction->value,
             'nested' => [
                 'path' => 'search_data',
                 'filter' => [
                     'bool' => [
                         'must' => [
                             'term' => [
-                                'search_data.number_facet.facet_code' => $this->by->key(),
-                            ]
+                                'search_data.number_facet.facet_code' => $this->property->getKey(),
+                            ],
                         ],
                     ],
                 ],
             ],
         ];
-        $order = array_merge($order, $this->properties);
+
         return [
-            'search_data.number_facet.facet_value' => $order,
+            'search_data.number_facet.facet_value' => array_merge(
+                $order,
+                $this->additionalParams
+            ),
         ];
     }
 }
diff --git a/src/ElasticSearch/Result.php b/src/ElasticSearch/Result.php
index 54bc77648c4e7334368113e0197c46ed9222fb1b..09885ef408ac94326db683e4bc2bc2a755f7425d 100644
--- a/src/ElasticSearch/Result.php
+++ b/src/ElasticSearch/Result.php
@@ -3,18 +3,18 @@
 namespace IQDEV\ElasticSearch;
 
 use IQDEV\ElasticSearch\Document\ProductCollection;
-use IQDEV\ElasticSearch\Facet\FacetCollection;
+use IQDEV\ElasticSearch\Facet\Collection\FacetResultCollection;
 
 class Result
 {
     private ProductCollection $products;
-    private FacetCollection $facets;
+    private FacetResultCollection $facets;
     private int $total = 0;
 
     public function __construct()
     {
         $this->products = new ProductCollection();
-        $this->facets = new FacetCollection();
+        $this->facets = new FacetResultCollection();
     }
 
     public function setTotal(int $total): void
@@ -32,7 +32,7 @@ class Result
         return $this->products;
     }
 
-    public function getFacets(): FacetCollection
+    public function getFacets(): FacetResultCollection
     {
         return $this->facets;
     }
diff --git a/tests/Filter/AggsTest.php b/tests/Filter/AggsTest.php
index 163be9a9fa2020490f4c09351f6d6449421e3b39..b4b5275fa8161a62bc4415ea02d8f731ba38fb6f 100644
--- a/tests/Filter/AggsTest.php
+++ b/tests/Filter/AggsTest.php
@@ -2,19 +2,19 @@
 
 namespace IQDEV\ElasticSearchTests\Filter;
 
-use IQDEV\ElasticSearchTests\AbstractTestCase;
-use IQDEV\ElasticSearchTests\Helpers\FormatData;
-use IQDEV\ElasticSearchTests\Service\SearchClient;
 use IQDEV\ElasticSearch\Criteria;
+use IQDEV\ElasticSearch\Filter\Collection\FilterGroupCollection;
 use IQDEV\ElasticSearch\Filter\Field;
 use IQDEV\ElasticSearch\Filter\Filter;
-use IQDEV\ElasticSearch\Filter\FilterGroupCollection;
-use IQDEV\ElasticSearch\Filter\FilterKeyword;
-use IQDEV\ElasticSearch\Filter\FilterNumber;
 use IQDEV\ElasticSearch\Filter\FilterOperator;
 use IQDEV\ElasticSearch\Filter\FilterType;
 use IQDEV\ElasticSearch\Filter\LogicOperator;
+use IQDEV\ElasticSearch\Filter\Value\FilterKeyword;
+use IQDEV\ElasticSearch\Filter\Value\FilterNumber;
 use IQDEV\ElasticSearch\Query\SearchQuery;
+use IQDEV\ElasticSearchTests\AbstractTestCase;
+use IQDEV\ElasticSearchTests\Helpers\FormatData;
+use IQDEV\ElasticSearchTests\Service\SearchClient;
 
 /**
  * Тестирование агрегирующих функций
diff --git a/tests/Filter/CommonRangeKeywordsTest.php b/tests/Filter/CommonRangeKeywordsTest.php
index 4bcc8fd18639fcb71a619bec2b51166da6d92ab7..3495804d90cdcb3ea65c77734447c4522b8d9ee1 100644
--- a/tests/Filter/CommonRangeKeywordsTest.php
+++ b/tests/Filter/CommonRangeKeywordsTest.php
@@ -2,17 +2,17 @@
 
 namespace IQDEV\ElasticSearchTests\Filter;
 
-use IQDEV\ElasticSearchTests\AbstractTestCase;
-use IQDEV\ElasticSearchTests\Helpers\FormatData;
-use IQDEV\ElasticSearchTests\Service\SearchClient;
 use IQDEV\ElasticSearch\Criteria;
+use IQDEV\ElasticSearch\Filter\Collection\FilterGroupCollection;
 use IQDEV\ElasticSearch\Filter\Field;
 use IQDEV\ElasticSearch\Filter\Filter;
-use IQDEV\ElasticSearch\Filter\FilterGroupCollection;
-use IQDEV\ElasticSearch\Filter\FilterKeyword;
-use IQDEV\ElasticSearch\Filter\FilterNumber;
 use IQDEV\ElasticSearch\Filter\FilterOperator;
+use IQDEV\ElasticSearch\Filter\Value\FilterKeyword;
+use IQDEV\ElasticSearch\Filter\Value\FilterNumber;
 use IQDEV\ElasticSearch\Query\SearchQuery;
+use IQDEV\ElasticSearchTests\AbstractTestCase;
+use IQDEV\ElasticSearchTests\Helpers\FormatData;
+use IQDEV\ElasticSearchTests\Service\SearchClient;
 
 class CommonRangeKeywordsTest extends AbstractTestCase
 {
diff --git a/tests/Filter/KeywordsTest.php b/tests/Filter/KeywordsTest.php
index df62a19a4d8759c5d7022a0df020af0d8fbd7d05..c56a3c81bc15394fb648a63136d6f96711fdd68f 100644
--- a/tests/Filter/KeywordsTest.php
+++ b/tests/Filter/KeywordsTest.php
@@ -2,17 +2,17 @@
 
 namespace IQDEV\ElasticSearchTests\Filter;
 
-use IQDEV\ElasticSearchTests\AbstractTestCase;
-use IQDEV\ElasticSearchTests\Helpers\FormatData;
-use IQDEV\ElasticSearchTests\Service\SearchClient;
 use IQDEV\ElasticSearch\Criteria;
+use IQDEV\ElasticSearch\Filter\Collection\FilterGroupCollection;
 use IQDEV\ElasticSearch\Filter\Field;
 use IQDEV\ElasticSearch\Filter\Filter;
-use IQDEV\ElasticSearch\Filter\FilterGroupCollection;
-use IQDEV\ElasticSearch\Filter\FilterKeyword;
 use IQDEV\ElasticSearch\Filter\FilterOperator;
 use IQDEV\ElasticSearch\Filter\FilterType;
+use IQDEV\ElasticSearch\Filter\Value\FilterKeyword;
 use IQDEV\ElasticSearch\Query\SearchQuery;
+use IQDEV\ElasticSearchTests\AbstractTestCase;
+use IQDEV\ElasticSearchTests\Helpers\FormatData;
+use IQDEV\ElasticSearchTests\Service\SearchClient;
 
 class KeywordsTest extends AbstractTestCase
 {
diff --git a/tests/Filter/QueryAndPostFilterTest.php b/tests/Filter/QueryAndPostFilterTest.php
index 9ea7ecce4751035a8ceb074f23ff947724d857d4..b7f24c9bbff2cc1db16b1255c92f31cb66be67d9 100644
--- a/tests/Filter/QueryAndPostFilterTest.php
+++ b/tests/Filter/QueryAndPostFilterTest.php
@@ -2,19 +2,19 @@
 
 namespace IQDEV\ElasticSearchTests\Filter;
 
-use IQDEV\ElasticSearchTests\AbstractTestCase;
-use IQDEV\ElasticSearchTests\Helpers\FormatData;
-use IQDEV\ElasticSearchTests\Service\SearchClient;
 use IQDEV\ElasticSearch\Criteria;
+use IQDEV\ElasticSearch\Filter\Collection\FilterGroupCollection;
 use IQDEV\ElasticSearch\Filter\Field;
 use IQDEV\ElasticSearch\Filter\Filter;
-use IQDEV\ElasticSearch\Filter\FilterGroupCollection;
-use IQDEV\ElasticSearch\Filter\FilterKeyword;
-use IQDEV\ElasticSearch\Filter\FilterNumber;
 use IQDEV\ElasticSearch\Filter\FilterOperator;
 use IQDEV\ElasticSearch\Filter\FilterType;
 use IQDEV\ElasticSearch\Filter\LogicOperator;
+use IQDEV\ElasticSearch\Filter\Value\FilterKeyword;
+use IQDEV\ElasticSearch\Filter\Value\FilterNumber;
 use IQDEV\ElasticSearch\Query\SearchQuery;
+use IQDEV\ElasticSearchTests\AbstractTestCase;
+use IQDEV\ElasticSearchTests\Helpers\FormatData;
+use IQDEV\ElasticSearchTests\Service\SearchClient;
 
 class QueryAndPostFilterTest extends AbstractTestCase
 {
diff --git a/tests/Filter/QueryTest.php b/tests/Filter/QueryTest.php
index 2db833a1c8eb20352ef9e38e9a7c507147d0d4cc..6a017db7a50e4cdadf109cd344d8a58fb7b297ac 100644
--- a/tests/Filter/QueryTest.php
+++ b/tests/Filter/QueryTest.php
@@ -3,18 +3,18 @@
 namespace IQDEV\ElasticSearchTests\Filter;
 
 use IQDEV\ElasticSearch\Converter\CriteriaToEsRequest;
-use IQDEV\ElasticSearchTests\AbstractTestCase;
-use IQDEV\ElasticSearchTests\Helpers\FormatData;
-use IQDEV\ElasticSearchTests\Service\SearchClient;
 use IQDEV\ElasticSearch\Criteria;
+use IQDEV\ElasticSearch\Filter\Collection\FilterGroupCollection;
 use IQDEV\ElasticSearch\Filter\Field;
 use IQDEV\ElasticSearch\Filter\Filter;
-use IQDEV\ElasticSearch\Filter\FilterGroupCollection;
-use IQDEV\ElasticSearch\Filter\FilterKeyword;
-use IQDEV\ElasticSearch\Filter\FilterNumber;
 use IQDEV\ElasticSearch\Filter\FilterOperator;
 use IQDEV\ElasticSearch\Filter\FilterType;
+use IQDEV\ElasticSearch\Filter\Value\FilterKeyword;
+use IQDEV\ElasticSearch\Filter\Value\FilterNumber;
 use IQDEV\ElasticSearch\Query\SearchQuery;
+use IQDEV\ElasticSearchTests\AbstractTestCase;
+use IQDEV\ElasticSearchTests\Helpers\FormatData;
+use IQDEV\ElasticSearchTests\Service\SearchClient;
 
 /**
  * Тестирование агрегирующих функций
diff --git a/tests/Filter/RangeTest.php b/tests/Filter/RangeTest.php
index 9c9b03206e138c1d636652338578531df2eba1c5..3f0a3e306e0845499626e2b3b786c8c21d42e618 100644
--- a/tests/Filter/RangeTest.php
+++ b/tests/Filter/RangeTest.php
@@ -2,16 +2,16 @@
 
 namespace IQDEV\ElasticSearchTests\Filter;
 
-use IQDEV\ElasticSearchTests\AbstractTestCase;
-use IQDEV\ElasticSearchTests\Helpers\FormatData;
-use IQDEV\ElasticSearchTests\Service\SearchClient;
 use IQDEV\ElasticSearch\Criteria;
+use IQDEV\ElasticSearch\Filter\Collection\FilterGroupCollection;
 use IQDEV\ElasticSearch\Filter\Field;
 use IQDEV\ElasticSearch\Filter\Filter;
-use IQDEV\ElasticSearch\Filter\FilterGroupCollection;
-use IQDEV\ElasticSearch\Filter\FilterNumber;
 use IQDEV\ElasticSearch\Filter\FilterOperator;
+use IQDEV\ElasticSearch\Filter\Value\FilterNumber;
 use IQDEV\ElasticSearch\Query\SearchQuery;
+use IQDEV\ElasticSearchTests\AbstractTestCase;
+use IQDEV\ElasticSearchTests\Helpers\FormatData;
+use IQDEV\ElasticSearchTests\Service\SearchClient;
 
 class RangeTest extends AbstractTestCase
 {
diff --git a/tests/Filter/SearchItemsTest.php b/tests/Filter/SearchItemsTest.php
index 5327213aa5cda04bff6908e0ee6cc6cb9031f8e9..c1119af3a3ea900208e3420d0c50eaf124c91042 100644
--- a/tests/Filter/SearchItemsTest.php
+++ b/tests/Filter/SearchItemsTest.php
@@ -2,17 +2,17 @@
 
 namespace IQDEV\ElasticSearchTests\Filter;
 
-use IQDEV\ElasticSearchTests\AbstractTestCase;
-use IQDEV\ElasticSearchTests\Helpers\FormatData;
-use IQDEV\ElasticSearchTests\Service\SearchClient;
 use IQDEV\ElasticSearch\Criteria;
+use IQDEV\ElasticSearch\Filter\Collection\FilterGroupCollection;
 use IQDEV\ElasticSearch\Filter\Field;
 use IQDEV\ElasticSearch\Filter\Filter;
-use IQDEV\ElasticSearch\Filter\FilterGroupCollection;
-use IQDEV\ElasticSearch\Filter\FilterKeyword;
 use IQDEV\ElasticSearch\Filter\FilterOperator;
 use IQDEV\ElasticSearch\Filter\FilterType;
+use IQDEV\ElasticSearch\Filter\Value\FilterKeyword;
 use IQDEV\ElasticSearch\Query\SearchQuery;
+use IQDEV\ElasticSearchTests\AbstractTestCase;
+use IQDEV\ElasticSearchTests\Helpers\FormatData;
+use IQDEV\ElasticSearchTests\Service\SearchClient;
 
 class SearchItemsTest extends AbstractTestCase
 {
diff --git a/tests/Filter/SortTest.php b/tests/Filter/SortTest.php
index 9d4b4450de1ac3b50911d2c472a3011cfc4d0674..3ba6b7ff251292d981b689c204b870a72e416f58 100644
--- a/tests/Filter/SortTest.php
+++ b/tests/Filter/SortTest.php
@@ -2,17 +2,14 @@
 
 namespace IQDEV\ElasticSearchTests\Filter;
 
-use IQDEV\ElasticSearch\Order\OrderAscType;
-use IQDEV\ElasticSearch\Order\OrderDescType;
-use IQDEV\ElasticSearch\Order\OrderKeywordProperty;
-use IQDEV\ElasticSearch\Order\OrderNumberProperty;
+use IQDEV\ElasticSearch\Document\Property\Property;
+use IQDEV\ElasticSearch\Order\OrderDirection;
+use IQDEV\ElasticSearch\Order\OrderFactory;
 use IQDEV\ElasticSearchTests\AbstractTestCase;
 use IQDEV\ElasticSearchTests\Helpers\FormatData;
 use IQDEV\ElasticSearchTests\Service\SearchClient;
 use IQDEV\ElasticSearch\Criteria;
-use IQDEV\ElasticSearch\Document\Property\AttrType;
 use IQDEV\ElasticSearch\Document\Property\PropertyType;
-use IQDEV\ElasticSearch\Order\Order;
 use IQDEV\ElasticSearch\Query\SearchQuery;
 
 class SortTest extends AbstractTestCase
@@ -26,10 +23,9 @@ class SortTest extends AbstractTestCase
     {
         $criteria = new Criteria();
 
-        $criteria->sorting()->add(new Order(
-            new AttrType('category_id'),
-            new OrderAscType(),
-        ));
+        $criteria->sorting()->add(
+            OrderFactory::createByProperty(new Property('category_id'), OrderDirection::ASC)
+        );
 
         $q = new SearchQuery($criteria);
 
@@ -62,10 +58,9 @@ class SortTest extends AbstractTestCase
     {
         $criteria = new Criteria();
 
-        $criteria->sorting()->add(new Order(
-            new AttrType('category_id'),
-            new OrderDescType(),
-        ));
+        $criteria->sorting()->add(
+            OrderFactory::createByProperty(new Property('category_id'), OrderDirection::DESC)
+        );
 
         $q = new SearchQuery($criteria);
 
@@ -98,10 +93,9 @@ class SortTest extends AbstractTestCase
     {
         $criteria = new Criteria();
 
-        $criteria->sorting()->add(new OrderKeywordProperty(
-            new PropertyType('color', PropertyType::TYPE_KEYWORD),
-            new OrderAscType(),
-        ));
+        $criteria->sorting()->add(
+            OrderFactory::createByProperty(new Property('color', PropertyType::KEYWORD), OrderDirection::ASC)
+        );
 
         $q = new SearchQuery($criteria);
 
@@ -134,10 +128,9 @@ class SortTest extends AbstractTestCase
     {
         $criteria = new Criteria();
 
-        $criteria->sorting()->add(new OrderKeywordProperty(
-            new PropertyType('color', PropertyType::TYPE_KEYWORD),
-            new OrderDescType(),
-        ));
+        $criteria->sorting()->add(
+            OrderFactory::createByProperty(new Property('color', PropertyType::KEYWORD), OrderDirection::DESC)
+        );
 
         $q = new SearchQuery($criteria);
 
@@ -170,10 +163,9 @@ class SortTest extends AbstractTestCase
     {
         $criteria = new Criteria();
 
-        $criteria->sorting()->add(new OrderNumberProperty(
-            new PropertyType('price', PropertyType::TYPE_NUMBER),
-            new OrderAscType(),
-        ));
+        $criteria->sorting()->add(
+            OrderFactory::createByProperty(new Property('price', PropertyType::NUMBER), OrderDirection::ASC)
+        );
 
         $q = new SearchQuery($criteria);
 
@@ -206,10 +198,9 @@ class SortTest extends AbstractTestCase
     {
         $criteria = new Criteria();
 
-        $criteria->sorting()->add(new OrderNumberProperty(
-            new PropertyType('price', PropertyType::TYPE_NUMBER),
-            new OrderDescType(),
-        ));
+        $criteria->sorting()->add(
+            OrderFactory::createByProperty(new Property('price', PropertyType::NUMBER), OrderDirection::DESC)
+        );
 
         $q = new SearchQuery($criteria);
 
@@ -242,10 +233,9 @@ class SortTest extends AbstractTestCase
     {
         $criteria = new Criteria();
 
-        $criteria->sorting()->add(new Order(
-            new PropertyType('size', PropertyType::TYPE_KEYWORD),
-            new OrderAscType(),
-        ));
+        $criteria->sorting()->add(
+            OrderFactory::createByProperty(new Property('size', PropertyType::KEYWORD), OrderDirection::ASC)
+        );
 
         $q = new SearchQuery($criteria);
 
@@ -278,10 +268,9 @@ class SortTest extends AbstractTestCase
     {
         $criteria = new Criteria();
 
-        $criteria->sorting()->add(new Order(
-            new PropertyType('size', PropertyType::TYPE_KEYWORD),
-            new OrderDescType(),
-        ));
+        $criteria->sorting()->add(
+            OrderFactory::createByProperty(new Property('size', PropertyType::KEYWORD), OrderDirection::DESC)
+        );
 
         $q = new SearchQuery($criteria);
 
diff --git a/tests/Helpers/FormatData.php b/tests/Helpers/FormatData.php
index 7914eedffd0f1132beb05af3c32c3767e652e3fb..233bcced7e1cbfec7a1e0e3d4d2b8293a82acfd4 100644
--- a/tests/Helpers/FormatData.php
+++ b/tests/Helpers/FormatData.php
@@ -3,11 +3,9 @@
 namespace IQDEV\ElasticSearchTests\Helpers;
 
 use IQDEV\ElasticSearch\Document\Product;
-use IQDEV\ElasticSearch\Facet\Facet;
+use IQDEV\ElasticSearch\Facet\FacetResult;
 use IQDEV\ElasticSearch\Facet\Item\FacetItemList;
 use IQDEV\ElasticSearch\Facet\Item\FacetItemRange;
-use IQDEV\ElasticSearch\Facet\Type\FacetListType;
-use IQDEV\ElasticSearch\Facet\Type\FacetRangeType;
 use IQDEV\ElasticSearch\Result;
 
 class FormatData
@@ -28,11 +26,11 @@ class FormatData
         $aResult         = ['facets' => []];
         $aResult['hits'] = static::formatData($result)['hits'];
         foreach ($result->getFacets() as $facet) {
-            /** @var Facet $facet */
+            /** @var FacetResult $facet */
             $dataFacet = [
                 'code' => $facet->getCode(),
                 'label' => null, // $facet->getLabel(),
-                'type' => $facet->getType() instanceof FacetRangeType ? 'range' : ($facet->getType() instanceof FacetListType ? 'list' : null),
+                'type' => $facet->getType()->value,
                 'items' => [
                     'list' => [],
                     'range' => []
diff --git a/tests/Helpers/TestIndexProvider.php b/tests/Helpers/TestIndexProvider.php
index 89761f057372389acdb74884a098905dd209bdd4..070d24c02204e6e5dca6782d8e89c6a07b3cb8e4 100644
--- a/tests/Helpers/TestIndexProvider.php
+++ b/tests/Helpers/TestIndexProvider.php
@@ -4,9 +4,9 @@ namespace IQDEV\ElasticSearchTests\Helpers;
 
 use IQDEV\ElasticSearch\Configuration;
 use IQDEV\ElasticSearch\Document\ProductDocument;
-use IQDEV\ElasticSearch\Facet\FacetCategory;
-use IQDEV\ElasticSearch\Facet\FacetKeyword;
-use IQDEV\ElasticSearch\Facet\FacetNumber;
+use IQDEV\ElasticSearch\Document\Property\Property;
+use IQDEV\ElasticSearch\Document\Property\PropertyType;
+use IQDEV\ElasticSearch\Facet\FacetFactory;
 use IQDEV\ElasticSearch\Indexer\AddIndex;
 use IQDEV\ElasticSearch\Indexer\DeleteIndex;
 use IQDEV\ElasticSearch\Indexer\IndexProvider;
@@ -30,7 +30,9 @@ class TestIndexProvider implements IndexProvider
     public function get(): \Generator
     {
         foreach ($this->products as $product) {
-            $document = new ProductDocument(new FacetCategory($product['category']));
+            $document = new ProductDocument(
+                FacetFactory::createFromProperty(new Property('category_id', PropertyType::BASE), $product['category'])
+            );
             //todo по-хорошему нужны базовые классы, которые будут описывать свойства
             // и формировать структуру для последующей обработки
 
@@ -46,11 +48,15 @@ class TestIndexProvider implements IndexProvider
             $document->setAdditionData($data);
 
             if (isset($product['properties'])) {
-                foreach ($product['properties'] as $key => $prop) {
+                foreach ($product['properties'] as $key => $value) {
                     if ($key === 'price') {
-                        $document->getNumberFacets()->add(new FacetNumber($key, $prop));
+                        $document->getNumberFacets()->add(
+                            FacetFactory::createFromProperty(new Property($key, PropertyType::NUMBER), $value)
+                        );
                     } else {
-                        $document->getKeywordFacets()->add(new FacetKeyword($key, $prop));
+                        $document->getKeywordFacets()->add(
+                            FacetFactory::createFromProperty(new Property($key, PropertyType::KEYWORD), $value)
+                        );
                     }
                 }
             }