Skip to content

Commit ae3abc8

Browse files
committed
Add paginated result + fix missing total result count
1 parent 592ee1f commit ae3abc8

File tree

5 files changed

+156
-6
lines changed

5 files changed

+156
-6
lines changed

src/Aggregate.php

Lines changed: 17 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,7 @@
3333
use MacFJA\RediSearch\Aggregate\Result;
3434
use MacFJA\RediSearch\Aggregate\SortBy;
3535
use MacFJA\RediSearch\Helper\DataHelper;
36+
use MacFJA\RediSearch\Helper\PaginatedResult;
3637
use MacFJA\RediSearch\Helper\RedisHelper;
3738
use Predis\Client;
3839
use Throwable;
@@ -217,20 +218,33 @@ public function withFilter(string $filter): Aggregate
217218

218219
/**
219220
* @return array<Result>
221+
*
222+
* @deprecated Use \MacFJA\RediSearch\Aggregate::execute
220223
*/
221224
public function aggregate(): array
225+
{
226+
return $this->execute()->getItems();
227+
}
228+
229+
/**
230+
* @return PaginatedResult<Result>
231+
*/
232+
public function execute()
222233
{
223234
$rawResult = $this->redis->executeRaw($this->buildQuery());
224235

225-
array_shift($rawResult);
236+
$totalCount = array_shift($rawResult);
237+
assert(is_int($totalCount));
226238

227-
$results = array_map(function (array $document) {
239+
$items = array_map(function (array $document) {
228240
return new Result(RedisHelper::getPairs($document));
229241
}, $rawResult);
230242

243+
$result = new class($totalCount, $items, 0, 0) extends PaginatedResult {
244+
};
231245
$this->reset();
232246

233-
return $results;
247+
return $result;
234248
}
235249

236250
/**

src/Builder.php

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -24,4 +24,9 @@
2424
interface Builder
2525
{
2626
public function reset(): self;
27+
28+
/**
29+
* @return mixed
30+
*/
31+
public function execute();
2732
}

src/Helper/PaginatedResult.php

Lines changed: 105 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,105 @@
1+
<?php
2+
3+
declare(strict_types=1);
4+
5+
/*
6+
* Copyright MacFJA
7+
*
8+
* Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated
9+
* documentation files (the "Software"), to deal in the Software without restriction, including without limitation the
10+
* rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to
11+
* permit persons to whom the Software is furnished to do so, subject to the following conditions:
12+
*
13+
* The above copyright notice and this permission notice shall be included in all copies or substantial portions of the
14+
* Software.
15+
*
16+
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE
17+
* WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
18+
* COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
19+
* OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
20+
*/
21+
22+
namespace MacFJA\RediSearch\Helper;
23+
24+
use function ceil;
25+
use function count;
26+
27+
/**
28+
* @template T
29+
*/
30+
abstract class PaginatedResult
31+
{
32+
/** @var int */
33+
private $totalCount;
34+
35+
/** @var array<T> */
36+
private $items;
37+
38+
/** @var int */
39+
private $offset;
40+
41+
/** @var int */
42+
private $pageSize;
43+
44+
/**
45+
* @param array<T> $items
46+
*/
47+
public function __construct(int $totalCount, array $items, int $offset, int $pageSize)
48+
{
49+
$this->totalCount = $totalCount;
50+
$this->items = $items;
51+
$this->offset = $offset;
52+
$this->pageSize = $pageSize;
53+
}
54+
55+
public function getTotalCount(): int
56+
{
57+
return $this->totalCount;
58+
}
59+
60+
/**
61+
* @return array<T>
62+
*/
63+
public function getItems(): array
64+
{
65+
return $this->items;
66+
}
67+
68+
public function getOffset(): int
69+
{
70+
return $this->offset;
71+
}
72+
73+
public function getPageSize(): int
74+
{
75+
return $this->pageSize;
76+
}
77+
78+
public function getPageNumber(): int
79+
{
80+
if (0 === $this->pageSize) {
81+
return 0;
82+
}
83+
84+
return (int) ceil($this->getOffset() / $this->pageSize) + 1;
85+
}
86+
87+
public function havePreviousPage(): bool
88+
{
89+
return $this->offset > 0;
90+
}
91+
92+
public function haveNextPage(): bool
93+
{
94+
return $this->offset + count($this->items) < $this->totalCount;
95+
}
96+
97+
public function getPageCount(): int
98+
{
99+
if (0 === $this->pageSize) {
100+
return 0;
101+
}
102+
103+
return (int) ceil($this->totalCount / $this->pageSize);
104+
}
105+
}

src/Index/Builder.php

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -283,7 +283,15 @@ public function reset(): \MacFJA\RediSearch\Builder
283283
return $this;
284284
}
285285

286+
/**
287+
* @deprecated Use \MacFJA\RediSearch\Index\Builder::execute()
288+
*/
286289
public function create(): bool
290+
{
291+
return $this->execute();
292+
}
293+
294+
public function execute(): bool
287295
{
288296
$this->validateData();
289297
$query = $this->createRequest();

src/Search.php

Lines changed: 21 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,7 @@
3333
use function is_int;
3434
use function is_string;
3535
use MacFJA\RediSearch\Helper\DataHelper;
36+
use MacFJA\RediSearch\Helper\PaginatedResult;
3637
use MacFJA\RediSearch\Helper\RedisHelper;
3738
use MacFJA\RediSearch\Index\Builder as IndexBuilder;
3839
use MacFJA\RediSearch\Search\Exception\UnsupportedLanguageException;
@@ -54,6 +55,10 @@ class Search implements Builder
5455

5556
public const SORT_DESC = 'DESC';
5657

58+
private const DEFAULT_OFFSET = 0;
59+
60+
private const DEFAULT_LIMIT = 10;
61+
5762
/** @var Client */
5863
private $redis;
5964

@@ -378,13 +383,24 @@ public function withResultLimit(int $resultLimit): Search
378383

379384
/**
380385
* @return array<Result>
386+
*
387+
* @deprecated Use \MacFJA\RediSearch\Search::execute()
381388
*/
382389
public function search(): array
390+
{
391+
return $this->execute()->getItems();
392+
}
393+
394+
/**
395+
* @return PaginatedResult<Result>
396+
*/
397+
public function execute(): PaginatedResult
383398
{
384399
$rawResult = $this->redis->executeRaw($this->buildQuery());
385400
DataHelper::handleRawResult($rawResult);
386401

387-
array_shift($rawResult);
402+
$totalCount = array_shift($rawResult);
403+
assert(is_int($totalCount));
388404

389405
$chunkSize = 2 // Hash + fields
390406
+ ($this->withScores ? 1 : 0)
@@ -393,7 +409,7 @@ public function search(): array
393409

394410
$documents = array_chunk($rawResult, $chunkSize);
395411

396-
$results = array_map(function ($document) {
412+
$items = array_map(function ($document) {
397413
$hash = array_shift($document) ?? '';
398414
$score = $this->withScores ? (float) array_shift($document) : null;
399415
$payload = $this->withPayloads ? array_shift($document) : null;
@@ -409,9 +425,11 @@ public function search(): array
409425
return new Result($hash, $fields, $score, $payload, $sortKey);
410426
}, $documents);
411427

428+
$result = new class($totalCount, $items, $this->resultOffset ?? self::DEFAULT_OFFSET, $this->resultLimit ?? self::DEFAULT_LIMIT) extends PaginatedResult {
429+
};
412430
$this->reset();
413431

414-
return $results;
432+
return $result;
415433
}
416434

417435
/**

0 commit comments

Comments
 (0)