Skip to content

Commit

Permalink
feat: GeoLocatedFilter (#17)
Browse files Browse the repository at this point in the history
  • Loading branch information
sitepark-veltrup authored Dec 2, 2024
1 parent db9c26c commit 19b0add
Show file tree
Hide file tree
Showing 5 changed files with 94 additions and 68 deletions.
21 changes: 21 additions & 0 deletions src/Dto/Search/Query/Filter/GeoLocatedFilter.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
<?php

declare(strict_types=1);

namespace Atoolo\Search\Dto\Search\Query\Filter;

/**
* @codeCoverageIgnore
*/
class GeoLocatedFilter extends Filter
{
public function __construct(
public readonly bool $exists,
?string $key = null,
) {
parent::__construct(
$key,
$key !== null ? [$key] : [],
);
}
}
70 changes: 26 additions & 44 deletions src/Service/Search/Schema2xFieldMapper.php
Original file line number Diff line number Diff line change
Expand Up @@ -13,10 +13,10 @@
use Atoolo\Search\Dto\Search\Query\Facet\RelativeDateRangeFacet;
use Atoolo\Search\Dto\Search\Query\Facet\SiteFacet;
use Atoolo\Search\Dto\Search\Query\Filter\AbsoluteDateRangeFilter;
use Atoolo\Search\Dto\Search\Query\Filter\ArchiveFilter;
use Atoolo\Search\Dto\Search\Query\Filter\CategoryFilter;
use Atoolo\Search\Dto\Search\Query\Filter\ContentSectionTypeFilter;
use Atoolo\Search\Dto\Search\Query\Filter\Filter;
use Atoolo\Search\Dto\Search\Query\Filter\GeoLocatedFilter;
use Atoolo\Search\Dto\Search\Query\Filter\GroupFilter;
use Atoolo\Search\Dto\Search\Query\Filter\IdFilter;
use Atoolo\Search\Dto\Search\Query\Filter\ObjectTypeFilter;
Expand All @@ -37,25 +37,17 @@ class Schema2xFieldMapper
{
public function getFacetField(Facet $facet): string
{
switch (true) {
case $facet instanceof CategoryFacet:
return 'sp_category_path';
case $facet instanceof ContentSectionTypeFacet:
return 'sp_contenttype';
case $facet instanceof GroupFacet:
return 'sp_group_path';
case $facet instanceof ObjectTypeFacet:
return 'sp_objecttype';
case $facet instanceof SiteFacet:
return 'sp_site';
case $facet instanceof RelativeDateRangeFacet:
case $facet instanceof AbsoluteDateRangeFacet:
return 'sp_date_list';
default:
throw new InvalidArgumentException(
'Unsupported facet-field-class ' . get_class($facet),
);
}
return match (true) {
$facet instanceof CategoryFacet => 'sp_category_path',
$facet instanceof ContentSectionTypeFacet => 'sp_contenttype',
$facet instanceof GroupFacet => 'sp_group_path',
$facet instanceof ObjectTypeFacet => 'sp_objecttype',
$facet instanceof SiteFacet => 'sp_site',
$facet instanceof RelativeDateRangeFacet, $facet instanceof AbsoluteDateRangeFacet => 'sp_date_list',
default => throw new InvalidArgumentException(
'Unsupported facet-field-class ' . get_class($facet),
),
};
}

public function getArchiveField(): string
Expand All @@ -71,30 +63,20 @@ public function getGeoPointField(): string

public function getFilterField(Filter $filter): string
{
switch (true) {
case $filter instanceof IdFilter:
return 'id';
case $filter instanceof CategoryFilter:
return 'sp_category_path';
case $filter instanceof ContentSectionTypeFilter:
return 'sp_contenttype';
case $filter instanceof GroupFilter:
return 'sp_group_path';
case $filter instanceof ObjectTypeFilter:
return 'sp_objecttype';
case $filter instanceof SiteFilter:
return 'sp_site';
case $filter instanceof RelativeDateRangeFilter:
case $filter instanceof AbsoluteDateRangeFilter:
return 'sp_date_list';
case $filter instanceof SpatialOrbitalFilter:
case $filter instanceof SpatialArbitraryRectangleFilter:
return $this->getGeoPointField();
default:
throw new InvalidArgumentException(
'Unsupported filter-field-class ' . get_class($filter),
);
}
return match (true) {
$filter instanceof IdFilter => 'id',
$filter instanceof CategoryFilter => 'sp_category_path',
$filter instanceof ContentSectionTypeFilter => 'sp_contenttype',
$filter instanceof GroupFilter => 'sp_group_path',
$filter instanceof ObjectTypeFilter => 'sp_objecttype',
$filter instanceof SiteFilter => 'sp_site',
$filter instanceof RelativeDateRangeFilter, $filter instanceof AbsoluteDateRangeFilter => 'sp_date_list',
$filter instanceof SpatialOrbitalFilter, $filter instanceof SpatialArbitraryRectangleFilter => $this->getGeoPointField(),
$filter instanceof GeoLocatedFilter => 'sp_geo_points',
default => throw new InvalidArgumentException(
'Unsupported filter-field-class ' . get_class($filter),
),
};
}

public function getSortField(Criteria $criteria): string
Expand Down
46 changes: 22 additions & 24 deletions src/Service/Search/SolrQueryFilterAppender.php
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@
use Atoolo\Search\Dto\Search\Query\Filter\AndFilter;
use Atoolo\Search\Dto\Search\Query\Filter\FieldFilter;
use Atoolo\Search\Dto\Search\Query\Filter\Filter;
use Atoolo\Search\Dto\Search\Query\Filter\GeoLocatedFilter;
use Atoolo\Search\Dto\Search\Query\Filter\NotFilter;
use Atoolo\Search\Dto\Search\Query\Filter\OrFilter;
use Atoolo\Search\Dto\Search\Query\Filter\QueryFilter;
Expand Down Expand Up @@ -42,30 +43,21 @@ public function append(Filter $filter): void

private function getQuery(Filter $filter): string
{
switch (true) {
case $filter instanceof FieldFilter:
return $this->getFieldQuery($filter);
case $filter instanceof AndFilter:
return $this->getAndQuery($filter);
case $filter instanceof OrFilter:
return $this->getOrQuery($filter);
case $filter instanceof NotFilter:
return 'NOT ' . $this->getQuery($filter->filter);
case $filter instanceof QueryFilter:
return $filter->query;
case $filter instanceof AbsoluteDateRangeFilter:
return $this->getAbsoluteDateRangeQuery($filter);
case $filter instanceof RelativeDateRangeFilter:
return $this->getRelativeDateRangeQuery($filter);
case $filter instanceof SpatialOrbitalFilter:
return $this->getSpatialOrbitalQuery($filter);
case $filter instanceof SpatialArbitraryRectangleFilter:
return $this->getSpatialArbitraryRectangleQuery($filter);
default:
throw new InvalidArgumentException(
'unsupported filter ' . get_class($filter),
);
}
return match (true) {
$filter instanceof FieldFilter => $this->getFieldQuery($filter),
$filter instanceof AndFilter => $this->getAndQuery($filter),
$filter instanceof OrFilter => $this->getOrQuery($filter),
$filter instanceof NotFilter => 'NOT ' . $this->getQuery($filter->filter),
$filter instanceof QueryFilter => $filter->query,
$filter instanceof AbsoluteDateRangeFilter => $this->getAbsoluteDateRangeQuery($filter),
$filter instanceof RelativeDateRangeFilter => $this->getRelativeDateRangeQuery($filter),
$filter instanceof SpatialOrbitalFilter => $this->getSpatialOrbitalQuery($filter),
$filter instanceof SpatialArbitraryRectangleFilter => $this->getSpatialArbitraryRectangleQuery($filter),
$filter instanceof GeoLocatedFilter => $this->getGeoLocatedQuery($filter),
default => throw new InvalidArgumentException(
'unsupported filter ' . get_class($filter),
),
};
}

private function getAndQuery(AndFilter $andFilter): string
Expand All @@ -88,6 +80,12 @@ private function getOrQuery(OrFilter $orFilter): string
return '(' . implode(' OR ', $query) . ')';
}

private function getGeoLocatedQuery(GeoLocatedFilter $filter): string
{
$field = $this->getFilterField($filter);
return ($filter->exists ? '' : '-') . $field . ':*';
}

private function getFieldQuery(FieldFilter $filter): string
{
$field = $this->getFilterField($filter);
Expand Down
2 changes: 2 additions & 0 deletions test/Service/Search/Schema2xFieldMapperTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@
use Atoolo\Search\Dto\Search\Query\Filter\CategoryFilter;
use Atoolo\Search\Dto\Search\Query\Filter\ContentSectionTypeFilter;
use Atoolo\Search\Dto\Search\Query\Filter\Filter;
use Atoolo\Search\Dto\Search\Query\Filter\GeoLocatedFilter;
use Atoolo\Search\Dto\Search\Query\Filter\GroupFilter;
use Atoolo\Search\Dto\Search\Query\Filter\IdFilter;
use Atoolo\Search\Dto\Search\Query\Filter\ObjectTypeFilter;
Expand Down Expand Up @@ -79,6 +80,7 @@ public static function getFilter(): array
[ SiteFilter::class, 'sp_site' ],
[ RelativeDateRangeFilter::class, 'sp_date_list' ],
[ AbsoluteDateRangeFilter::class, 'sp_date_list' ],
[ GeoLocatedFilter::class, 'sp_geo_points' ],
[ SpatialOrbitalFilter::class, 'sp_geo_points' ],
[ SpatialArbitraryRectangleFilter::class, 'sp_geo_points' ],
];
Expand Down
23 changes: 23 additions & 0 deletions test/Service/Search/SolrQueryFilterAppenderTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@
use Atoolo\Search\Dto\Search\Query\Filter\AndFilter;
use Atoolo\Search\Dto\Search\Query\Filter\FieldFilter;
use Atoolo\Search\Dto\Search\Query\Filter\Filter;
use Atoolo\Search\Dto\Search\Query\Filter\GeoLocatedFilter;
use Atoolo\Search\Dto\Search\Query\Filter\NotFilter;
use Atoolo\Search\Dto\Search\Query\Filter\OrFilter;
use Atoolo\Search\Dto\Search\Query\Filter\QueryFilter;
Expand Down Expand Up @@ -170,6 +171,28 @@ public function testAbsoluteDateRangeFilterWithTo(): void
$this->appender->append($filter);
}

public function testGeoLocatedFilterExistsTrue(): void
{
$filter = new GeoLocatedFilter(true);

$this->filterQuery->expects($this->once())
->method('setQuery')
->with('test:*');

$this->appender->append($filter);
}

public function testGeoLocatedFilterExistsFalse(): void
{
$filter = new GeoLocatedFilter(false);

$this->filterQuery->expects($this->once())
->method('setQuery')
->with('-test:*');

$this->appender->append($filter);
}

public function testSpatialOrbitalFilterWithGreateCircleDistanceMode(): void
{
$filter = new SpatialOrbitalFilter(
Expand Down

0 comments on commit 19b0add

Please sign in to comment.