-
-
Notifications
You must be signed in to change notification settings - Fork 1.1k
Closed
Description
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:
- what is the point of the
apply
method if it never gets called on runtime - some sort of a BC/adapter thing? - what is a reasonable code example of a custom filter? The docs only show an example of an extension:
class AndOperatorFilterExtension implements RequestBodySearchCollectionExtensionInterface
{
public function applyToCollection(array $requestBody, string $resourceClass, ?Operation $operation = null, array $context = []): array;
{
$requestBody['query'] = $requestBody['query'] ?? [];
$andQuery = [
'query' => $context['filters']['fullName'],
'operator' => 'and',
];
$requestBody['query']['constant_score']['filter']['bool']['must'][0]['match']['full_name'] = $andQuery;
return $requestBody;
}
}
However this example would not work by itself, as it does not implement AbstractFilter
nor FilterInterface
. A more complete example together with an example of the annotation such as
#[ApiFilter(CustomGeoDistanceFilter::class, properties: ['locations.point' => 'geo_distance'])]
class SearchOffer
{
}
would be very appreciated.
Thanks
Metadata
Metadata
Assignees
Labels
No labels