Skip to content

Commit 5064c02

Browse files
committed
Convert $near into $geoWithin for count
1 parent 046b92a commit 5064c02

File tree

2 files changed

+37
-3
lines changed

2 files changed

+37
-3
lines changed

src/Query/Builder.php

Lines changed: 16 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -297,10 +297,9 @@ public function toMql(): array
297297
$columns = [];
298298
}
299299

300-
$wheres = $this->compileWheres();
301-
302300
// Use MongoDB's aggregation framework when using grouping or aggregation functions.
303301
if ($this->groups || $this->aggregate) {
302+
$wheres = $this->compileWheres(aggregation: true);
304303
$group = [];
305304
$unwinds = [];
306305

@@ -404,6 +403,8 @@ public function toMql(): array
404403
return ['aggregate' => [$pipeline, $options]];
405404
}
406405

406+
$wheres = $this->compileWheres(aggregation: false);
407+
407408
// Distinct query
408409
if ($this->distinct) {
409410
// Return distinct results directly
@@ -414,6 +415,7 @@ public function toMql(): array
414415
return ['distinct' => [$column, $wheres, $options]];
415416
}
416417

418+
417419
// Normal query
418420
// Convert select columns to simple projections.
419421
$projection = array_fill_keys($columns, true);
@@ -1133,7 +1135,7 @@ public function where($column, $operator = null, $value = null, $boolean = 'and'
11331135
*
11341136
* @return array
11351137
*/
1136-
protected function compileWheres(): array
1138+
protected function compileWheres(bool $aggregation): array
11371139
{
11381140
// The wheres to compile.
11391141
$wheres = $this->wheres ?: [];
@@ -1150,6 +1152,17 @@ protected function compileWheres(): array
11501152
if (isset($this->conversion[$where['operator']])) {
11511153
$where['operator'] = $this->conversion[$where['operator']];
11521154
}
1155+
1156+
if ($where['operator'] === 'near' && isset($where['value']['$geometry']) && isset($where['value']['$maxDistance'])) {
1157+
$where['operator'] = 'geoWithin';
1158+
$where['value'] = [
1159+
'$centerSphere' => [
1160+
$where['value']['$geometry']['coordinates'],
1161+
// Convert meters to radians
1162+
$where['value']['$maxDistance'] / 6378100,
1163+
],
1164+
];
1165+
}
11531166
}
11541167

11551168
// Convert column name to string to use as array key

tests/QueryTest.php

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -574,6 +574,27 @@ public function testPaginateDistinct(): void
574574
User::distinct('age')->paginate(2);
575575
}
576576

577+
public function testPaginateNear(): void
578+
{
579+
User::insert([
580+
['name' => 'Store A', 'position' => [9.224596977233887, 52.03082275390625]],
581+
['name' => 'Store B', 'position' => [9.224596977233887, 52.03082275390625]],
582+
['name' => 'Store C', 'position' => [9.3731451034548, 52.10194]],
583+
]);
584+
585+
$query = User::where('position', 'near', [
586+
'$geometry' => [
587+
'type' => 'Point',
588+
'coordinates' => [9.3731451034546, 52.1019308],
589+
],
590+
'$maxDistance' => 50,
591+
]);
592+
$result = $query->paginate(); // this results in error
593+
594+
$this->assertCount(1, $result->items());
595+
$this->assertSame('Store C', $result->first()->name);
596+
}
597+
577598
public function testUpdate(): void
578599
{
579600
$this->assertEquals(1, User::where(['name' => 'John Doe'])->update(['name' => 'Jim Morrison']));

0 commit comments

Comments
 (0)