Skip to content

Commit

Permalink
Added sort from the request query param
Browse files Browse the repository at this point in the history
  • Loading branch information
erikpach authored and pionl committed Feb 11, 2021
1 parent 9b944de commit 3ffc8ae
Show file tree
Hide file tree
Showing 5 changed files with 126 additions and 1 deletion.
3 changes: 2 additions & 1 deletion composer.json
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,8 @@
"illuminate/pagination": ">=5.5",
"illuminate/console": ">=5.5",
"elasticsearch/elasticsearch": "^7",
"erichard/elasticsearch-query-builder": "dev-collapse-and-improvments#9551a1e51d4059121072130716a9a31357283a08"
"erichard/elasticsearch-query-builder": "dev-collapse-and-improvments#9551a1e51d4059121072130716a9a31357283a08",
"illuminate/validation": ">=5.5"
},
"require-dev": {
"friendsofphp/php-cs-fixer": "^2.16",
Expand Down
32 changes: 32 additions & 0 deletions readme.md
Original file line number Diff line number Diff line change
Expand Up @@ -148,6 +148,38 @@ Property mappings types using constants like:
by provided this option.
```

**Sorting**

To enable sortable behavior add `HasSorting` trait to your instance of `AbstractBuilder` and implement method `allowedSortFields`.

```
/**
* Allowed fields for sorting.
*
* Key is the name of the field in the query.
* Value is the name of the field in the index.
*
* @return array
*/
public function allowedSortFields(): array
{
return [
'goals' => 'goals_count',
'minutes' => 'played_minutes',
];
}
```
With sorting enabled you can sort the results using `sort` request query parameter. This parameter accepts list of fields for sorting in format `{field_name}:{sort_direction}`.
Available directions for sorting are `asc` and `desc` and if not specified the default sort direction is set to `asc`.
**Examples:**
`sort[]=goals`
`sort[]=goals:asc&sort[]=minutes:desc`
## TODO
- improve documentation
Expand Down
17 changes: 17 additions & 0 deletions src/Constants/SortDirections.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
<?php

namespace Lelastico\Constants;

final class SortDirections
{
public const ASC = 'asc';
public const DESC = 'desc';

public static function getAll(): array
{
return [
self::ASC,
self::DESC,
];
}
}
6 changes: 6 additions & 0 deletions src/Search/Query/AbstractBuilder.php
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@
use Lelastico\Indices\AbstractElasticIndex;
use Lelastico\Search\Query\Traits\AddQueries;
use Lelastico\Search\Query\Traits\HasPaginationSettings;
use Lelastico\Search\Query\Traits\HasSorting;
use Lelastico\Search\Query\Traits\LogQuery;
use Lelastico\Search\Query\Traits\ParseResultsFromHits;
use Psr\Log\LoggerInterface;
Expand Down Expand Up @@ -74,6 +75,11 @@ public function paginate(): LengthAwarePaginator
$this->query->addFilter($this->filter);
}

// Add sort if enabled
if (in_array(HasSorting::class, class_uses($this), true)) {
$this->addSort($this->query, $this->request);
}

// Build the query and improve it
$query = $this->query->getQuery();

Expand Down
69 changes: 69 additions & 0 deletions src/Search/Query/Traits/HasSorting.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,69 @@
<?php

namespace Lelastico\Search\Query\Traits;

use Erichard\ElasticQueryBuilder\QueryBuilder;
use Illuminate\Http\Request;
use Illuminate\Validation\Rule;
use Lelastico\Constants\SortDirections;

/**
* Adds sortable behavior to the query builder from the request "sort" query parameter.
*/
trait HasSorting
{
/**
* Allowed fields for sorting.
*
* Key is the name of the field in the query.
* Value is the name of the field in the index.
*
* [
* 'goals' => 'goals_count'
* 'minutes' => 'played_minutes'
* ]
*
* @return array
*/
abstract public function allowedSortFields(): array;

protected function addSort(QueryBuilder $query, Request $request): void
{
if ($request->missing('sort')) {
return;
}

$request->validate($this->getValidationRules());

foreach ($request->get('sort') as $sort) {
$exploded = explode(':', $sort);

$field = $this->allowedSortFields()[$exploded[0]];
$direction = $exploded[1] ?? SortDirections::ASC;

$query->addSort($field, $direction);
}
}

private function getSortFields(): array
{
$values = [];

foreach (array_keys($this->allowedSortFields()) as $field) {
$values[] = $field;
foreach (SortDirections::getAll() as $direction) {
$values[] = "{$field}:{$direction}";
}
}

return $values;
}

private function getValidationRules(): array
{
return [
'sort' => ['required', 'array'],
'sort.*' => ['required', 'string', Rule::in($this->getSortFields())],
];
}
}

0 comments on commit 3ffc8ae

Please sign in to comment.