Skip to content

Commit 9aea5b0

Browse files
committed
PHPORM-106 Implement pagination for groupBy queries
1 parent 899a235 commit 9aea5b0

File tree

2 files changed

+50
-0
lines changed

2 files changed

+50
-0
lines changed

src/Query/Builder.php

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -910,6 +910,28 @@ public function newQuery()
910910
return new static($this->connection, $this->grammar, $this->processor);
911911
}
912912

913+
public function runPaginationCountQuery($columns = ['*'])
914+
{
915+
if ($this->distinct) {
916+
throw new BadMethodCallException('Distinct queries cannot be used for pagination. Use GroupBy instead');
917+
}
918+
919+
if ($this->groups || $this->havings) {
920+
$without = $this->unions ? ['orders', 'limit', 'offset'] : ['columns', 'orders', 'limit', 'offset'];
921+
922+
$mql = $this->cloneWithout($without)
923+
->cloneWithoutBindings($this->unions ? ['order'] : ['select', 'order'])
924+
->toMql();
925+
926+
// Adds the $count stage to the pipeline
927+
$mql['aggregate'][0][] = ['$count' => 'aggregate'];
928+
929+
return $this->collection->aggregate($mql['aggregate'][0], $mql['aggregate'][1])->toArray();
930+
}
931+
932+
return parent::runPaginationCountQuery($columns);
933+
}
934+
913935
/**
914936
* Perform an update query.
915937
*

tests/QueryTest.php

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@
44

55
namespace MongoDB\Laravel\Tests;
66

7+
use BadMethodCallException;
78
use DateTimeImmutable;
89
use LogicException;
910
use MongoDB\BSON\Regex;
@@ -534,6 +535,33 @@ public function testCursorPaginate(): void
534535
$this->assertNull($results->first()->title);
535536
}
536537

538+
public function testPaginateGroup(): void
539+
{
540+
$results = User::groupBy('age')->paginate(2);
541+
$this->assertEquals(2, $results->count());
542+
$this->assertEquals(6, $results->total());
543+
$this->assertEquals(3, $results->lastPage());
544+
$this->assertEquals(1, $results->currentPage());
545+
$this->assertCount(2, $results->items());
546+
$this->assertNotNull($results->first()->age);
547+
548+
$results = User::groupBy('age')->paginate(4, page: 2);
549+
$this->assertEquals(2, $results->count());
550+
$this->assertEquals(6, $results->total());
551+
$this->assertEquals(2, $results->lastPage());
552+
$this->assertEquals(2, $results->currentPage());
553+
$this->assertCount(2, $results->items());
554+
$this->assertNotNull($results->first()->age);
555+
}
556+
557+
public function testPaginateDistinct(): void
558+
{
559+
$this->expectException(BadMethodCallException::class);
560+
$this->expectExceptionMessage('Distinct queries cannot be used for pagination. Use GroupBy instead');
561+
562+
User::distinct('age')->paginate(2);
563+
}
564+
537565
public function testUpdate(): void
538566
{
539567
$this->assertEquals(1, User::where(['name' => 'John Doe'])->update(['name' => 'Jim Morrison']));

0 commit comments

Comments
 (0)