Skip to content

Commit

Permalink
Convert $near into $geoWithin for count
Browse files Browse the repository at this point in the history
  • Loading branch information
GromNaN committed Jul 24, 2024
1 parent 046b92a commit a35d7d3
Show file tree
Hide file tree
Showing 3 changed files with 39 additions and 3 deletions.
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ All notable changes to this project will be documented in this file.
* Add `Query\Builder::incrementEach()` and `decrementEach()` methods by @SmallRuralDog in [#2550](https://github.com/mongodb/laravel-mongodb/pull/2550)
* Deprecate `Connection::collection()` and `Schema\Builder::collection()` methods by @GromNaN in [#3062](https://github.com/mongodb/laravel-mongodb/pull/3062)
* Deprecate `Model::$collection` property to customize collection name. Use `$table` instead by @GromNaN in [#3064](https://github.com/mongodb/laravel-mongodb/pull/3064)
* Convert `$near` to `$geoWithin` in queries using aggregation by @GromNaN in [#3073](https://github.com/mongodb/laravel-mongodb/pull/3073)

## [4.7.0] - 2024-07-19

Expand Down
20 changes: 17 additions & 3 deletions src/Query/Builder.php
Original file line number Diff line number Diff line change
Expand Up @@ -297,10 +297,9 @@ public function toMql(): array
$columns = [];
}

$wheres = $this->compileWheres();

// Use MongoDB's aggregation framework when using grouping or aggregation functions.
if ($this->groups || $this->aggregate) {
$wheres = $this->compileWheres(true);
$group = [];
$unwinds = [];

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

$wheres = $this->compileWheres();

// Distinct query
if ($this->distinct) {
// Return distinct results directly
Expand All @@ -414,6 +415,7 @@ public function toMql(): array
return ['distinct' => [$column, $wheres, $options]];
}


// Normal query
// Convert select columns to simple projections.
$projection = array_fill_keys($columns, true);
Expand Down Expand Up @@ -1133,7 +1135,7 @@ public function where($column, $operator = null, $value = null, $boolean = 'and'
*
* @return array
*/
protected function compileWheres(): array
protected function compileWheres(bool $aggregation = false): array
{
// The wheres to compile.
$wheres = $this->wheres ?: [];
Expand All @@ -1150,6 +1152,18 @@ protected function compileWheres(): array
if (isset($this->conversion[$where['operator']])) {
$where['operator'] = $this->conversion[$where['operator']];
}

// Convert $near to $geoWithin for aggregations
if ($aggregation && $where['operator'] === 'near' && isset($where['value']['$geometry']) && isset($where['value']['$maxDistance'])) {
$where['operator'] = 'geoWithin';
$where['value'] = [
'$centerSphere' => [
$where['value']['$geometry']['coordinates'],
// Convert meters to radians
$where['value']['$maxDistance'] / 6378100,
],
];
}
}

// Convert column name to string to use as array key
Expand Down
21 changes: 21 additions & 0 deletions tests/QueryTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -574,6 +574,27 @@ public function testPaginateDistinct(): void
User::distinct('age')->paginate(2);
}

public function testPaginateNear(): void
{
User::insert([
['name' => 'Store A', 'position' => [9.224596977233887, 52.03082275390625]],
['name' => 'Store B', 'position' => [9.224596977233887, 52.03082275390625]],
['name' => 'Store C', 'position' => [9.3731451034548, 52.10194]],
]);

$query = User::where('position', 'near', [
'$geometry' => [
'type' => 'Point',
'coordinates' => [9.3731451034546, 52.1019308],
],
'$maxDistance' => 50,
]);
$result = $query->paginate(); // this results in error

$this->assertCount(1, $result->items());
$this->assertSame('Store C', $result->first()->name);
}

public function testUpdate(): void
{
$this->assertEquals(1, User::where(['name' => 'John Doe'])->update(['name' => 'Jim Morrison']));
Expand Down

0 comments on commit a35d7d3

Please sign in to comment.