Skip to content
This repository was archived by the owner on Feb 28, 2025. It is now read-only.

PHPLIB-1337 Add tests on Geospatial Query Operators #25

Merged
merged 2 commits into from
Jan 16, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
39 changes: 39 additions & 0 deletions generator/config/query/geoIntersects.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -11,3 +11,42 @@ arguments:
name: geometry
type:
- geometry
tests:
-
name: 'Intersects a Polygon'
link: 'https://www.mongodb.com/docs/manual/reference/operator/query/geoIntersects/#intersects-a-polygon'
pipeline:
-
$match:
loc:
$geoIntersects:
$geometry:
type: 'Polygon'
coordinates:
-
- [ 0, 0 ]
- [ 3, 6 ]
- [ 6, 1 ]
- [ 0, 0 ]
-
name: 'Intersects a Big Polygon'
link: 'https://www.mongodb.com/docs/manual/reference/operator/query/geoIntersects/#intersects-a--big--polygon'
pipeline:
-
$match:
loc:
$geoIntersects:
$geometry:
type: 'Polygon'
coordinates:
-
- [ -100, 60 ]
- [ -100, 0 ]
- [ -100, -60 ]
- [ 100, -60 ]
- [ 100, 60 ]
- [ -100, 60 ]
crs:
type: 'name'
properties:
name: 'urn:x-mongodb:crs:strictwinding:EPSG:4326'
39 changes: 39 additions & 0 deletions generator/config/query/geoWithin.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -11,3 +11,42 @@ arguments:
name: geometry
type:
- geometry
tests:
-
name: 'Within a Polygon'
link: 'https://www.mongodb.com/docs/manual/reference/operator/query/geoWithin/#within-a-polygon'
pipeline:
-
$match:
loc:
$geoWithin:
$geometry:
type: 'Polygon'
coordinates:
-
- [ 0, 0 ]
- [ 3, 6 ]
- [ 6, 1 ]
- [ 0, 0 ]
-
name: 'Within a Big Polygon'
link: 'https://www.mongodb.com/docs/manual/reference/operator/query/geoWithin/#within-a--big--polygon'
pipeline:
-
$match:
loc:
$geoWithin:
$geometry:
type: 'Polygon'
coordinates:
-
- [ -100, 60 ]
- [ -100, 0 ]
- [ -100, -60 ]
- [ 100, -60 ]
- [ 100, 60 ]
- [ -100, 60 ]
crs:
type: 'name'
properties:
name: 'urn:x-mongodb:crs:strictwinding:EPSG:4326'
1 change: 1 addition & 0 deletions generator/config/query/geometry.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -19,3 +19,4 @@ arguments:
name: crs
type:
- object
optional: true
22 changes: 19 additions & 3 deletions generator/config/query/near.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ name: $near
link: 'https://www.mongodb.com/docs/manual/reference/operator/query/near/'
type:
- fieldQuery
encode: object
encode: dollar_object
description: |
Returns geospatial objects in proximity to a point. Requires a geospatial index. The 2dsphere and 2d indexes support $near.
arguments:
Expand All @@ -14,14 +14,30 @@ arguments:
-
name: maxDistance
type:
- int
- number
optional: true
description: |
Distance in meters. Limits the results to those documents that are at most the specified distance from the center point.
-
name: minDistance
type:
- int
- number
optional: true
description: |
Distance in meters. Limits the results to those documents that are at least the specified distance from the center point.
tests:
-
name: 'Query on GeoJSON Data'
link: 'https://www.mongodb.com/docs/manual/reference/operator/query/near/#query-on-geojson-data'
pipeline:
-
$match:
location:
$near:
$geometry:
type: 'Point'
coordinates:
- -73.9667
- 40.78
$minDistance: 1000
$maxDistance: 5000
20 changes: 17 additions & 3 deletions generator/config/query/nearSphere.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ name: $nearSphere
link: 'https://www.mongodb.com/docs/manual/reference/operator/query/nearSphere/'
type:
- fieldQuery
encode: object
encode: dollar_object
description: |
Returns geospatial objects in proximity to a point on a sphere. Requires a geospatial index. The 2dsphere and 2d indexes support $nearSphere.
arguments:
Expand All @@ -14,14 +14,28 @@ arguments:
-
name: maxDistance
type:
- int
- number
optional: true
description: |
Distance in meters.
-
name: minDistance
type:
- int
- number
optional: true
description: |
Distance in meters. Limits the results to those documents that are at least the specified distance from the center point.
tests:
-
name: 'Specify Center Point Using GeoJSON'
link: 'https://www.mongodb.com/docs/manual/reference/operator/query/nearSphere/#specify-center-point-using-geojson'
pipeline:
-
$match:
location:
$nearSphere:
$geometry:
type: 'Point'
coordinates: [-73.9667, 40.78]
$minDistance: 1000
$maxDistance: 5000
15 changes: 14 additions & 1 deletion src/Builder/BuilderEncoder.php
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@
use MongoDB\Exception\UnsupportedValueException;
use stdClass;

use function array_key_exists;
use function array_key_first;
use function assert;
use function get_debug_type;
Expand Down Expand Up @@ -182,7 +183,19 @@ private function encodeAsDollarObject(OperatorInterface $value): stdClass
continue;
}

$result->{'$' . $key} = $this->recursiveEncode($val);
$val = $this->recursiveEncode($val);

if ($key === 'geometry') {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We may want to consider introducing a special encoder for geo operators to extract this special logic.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

For everything related to geometry, we need to be compatible with a GeoJSON library instead of creating a $geometry object.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I agree. Apart from a couple of libraries that saw their last updates 9 years ago, the only PHP libraries are found are jmikola/geojson which is supported in Doctrine ODM, and brick/geo which is still in a pre-release (0.x) state but saw its last update a little more than a year ago. I'll defer to @jmikola's expertise on this.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Tracking in PHPLIB-1364

if (is_object($val) && property_exists($val, '$geometry')) {
$result->{'$geometry'} = $val->{'$geometry'};
} elseif (is_array($val) && array_key_exists('$geometry', $val)) {
$result->{'$geometry'} = $val->{'$geometry'};
} else {
$result->{'$geometry'} = $val;
}
} else {
$result->{'$' . $key} = $val;
}
}

return $this->wrap($value, $result);
Expand Down
20 changes: 10 additions & 10 deletions src/Builder/Query/FactoryTrait.php

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

9 changes: 5 additions & 4 deletions src/Builder/Query/GeometryOperator.php

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

20 changes: 11 additions & 9 deletions src/Builder/Query/NearOperator.php

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

20 changes: 11 additions & 9 deletions src/Builder/Query/NearSphereOperator.php

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Loading