api-platform / docs

API Platform documentation
https://api-platform.com/docs/
164 stars 1.05k forks source link

Elasticsearch - how to create a custom filter #1926

Open signor-pedro opened 4 months ago

signor-pedro commented 4 months ago

Hi, I was trying to create a custom filter for geo-distance query.

I had a very hard time understanding what to do - this section is documented rather poorly.

I ended up doing something like this:

use ApiPlatform\Elasticsearch\Extension\RequestBodySearchCollectionExtensionInterface;
use ApiPlatform\Elasticsearch\Filter\AbstractFilter;
use ApiPlatform\Metadata\Operation;

class GeoDistanceFilter extends AbstractFilter implements RequestBodySearchCollectionExtensionInterface
{
    public function apply(array $clauseBody, string $resourceClass, ?Operation $operation = null, array $context = []): array
    {
        throw new \LogicException(
            'This method is never called, but for some reason dictated by the AbstractFilter type.'
        );
    }

    public function applyToCollection(array $requestBody, string $resourceClass, ?Operation $operation = null, array $context = []): array
    {
        // Check for the presence of geo-search parameters
        $filters = $context['filters'] ?? [];

        if (!isset($filters['latitute'], $filters['longitude'], $filters['distance'])) {
            return $requestBody;
        }

        // ... construct and apply the geo-distance query ...

        return $requestBody;
    }

    public function getDescription(string $resourceClass): array
    {
        return [
            'latitute' => [
                'property' => 'lat',
                'type' => 'float',
                'required' => false,
                'description' => 'Latitude for geo-distance search.',
                'openapi' => [
                    'example' => 48.8566,
                ],
            ],
            'longitude' => [
                'property' => 'lon',
                'type' => 'float',
                'required' => false,
                'description' => 'Longitude for geo-distance search.',
                'openapi' => [
                    'example' => 2.3522,
                ],
            ],
            'distance' => [
                'property' => 'distance',
                'type' => 'string',
                'required' => false,
                'description' => 'The maximum distance from the point (lat, lon). Example: "30km".',
                'openapi' => [
                    'example' => '30km',
                ],
            ],
        ];
    }
}

I had a hard time understanding some of these concepts:

Thanks