diff --git a/src/Elasticsearch/Filter/RangeFilter.php b/src/Elasticsearch/Filter/RangeFilter.php new file mode 100644 index 00000000000..098a2730772 --- /dev/null +++ b/src/Elasticsearch/Filter/RangeFilter.php @@ -0,0 +1,131 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +declare(strict_types=1); + +namespace ApiPlatform\Elasticsearch\Filter; + +/** + * The range filter allows to find resources that [range](https://www.elastic.co/guide/en/elasticsearch/reference/current/query-dsl-range-query.html) the specified text on full text fields. + * + * Syntax: `?property[]=value`. + * + *
+ * + * ```php + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * book.range_filter + * + * + * + * + * + * ``` + * + *
+ * + * Given that the collection endpoint is `/books`, you can filter books by title content with the following query: `/books?title=Foundation`. + * + * @see https://www.elastic.co/guide/en/elasticsearch/reference/current/query-dsl-range-query.html + * + * @author Saifallah Azzabi + */ +final class RangeFilter extends AbstractSearchFilter +{ + public const GT = 'gt'; + + public const GTE = 'gte'; + + public const LT = 'lt'; + + public const LTE = 'lte'; + /** + * {@inheritdoc} + */ + protected function getQuery(string $property, array $values, ?string $nestedPath): array + { + $rangeQuery = ['range' => [$property => []]]; + + foreach ($values as $operator => $value) { + if (\in_array($operator, [self::GT, self::GTE, self::LT, self::LTE], true)) { + $rangeQuery['range'][$property][$operator] = $value; + } + } + + if (null !== $nestedPath) { + return ['nested' => ['path' => $nestedPath, 'query' => $rangeQuery]]; + } + + return $rangeQuery; + } +} diff --git a/src/Symfony/Bundle/Resources/config/elasticsearch.php b/src/Symfony/Bundle/Resources/config/elasticsearch.php index 212fa22343b..8db74e70ea9 100644 --- a/src/Symfony/Bundle/Resources/config/elasticsearch.php +++ b/src/Symfony/Bundle/Resources/config/elasticsearch.php @@ -18,6 +18,7 @@ use ApiPlatform\Elasticsearch\Extension\SortFilterExtension; use ApiPlatform\Elasticsearch\Filter\MatchFilter; use ApiPlatform\Elasticsearch\Filter\OrderFilter; +use ApiPlatform\Elasticsearch\Filter\RangeFilter; use ApiPlatform\Elasticsearch\Filter\TermFilter; use ApiPlatform\Elasticsearch\Metadata\Resource\Factory\ElasticsearchProviderResourceMetadataCollectionFactory; use ApiPlatform\Elasticsearch\Serializer\DocumentNormalizer; @@ -93,6 +94,12 @@ $services->alias(MatchFilter::class, 'api_platform.elasticsearch.match_filter'); + $services->set('api_platform.elasticsearch.range_filter', RangeFilter::class) + ->abstract() + ->parent('api_platform.elasticsearch.search_filter'); + + $services->alias(RangeFilter::class, 'api_platform.elasticsearch.range_filter'); + $services->set('api_platform.elasticsearch.order_filter', OrderFilter::class) ->abstract() ->args([