spring-data-mongodb icon indicating copy to clipboard operation
spring-data-mongodb copied to clipboard

Doing a count with a near query and GeoJson point

Open sebastian-firsching opened this issue 3 years ago • 4 comments

Count queries using $near or $nearSphere require a rewrite to $geoWithin. However, according to the official MongoDB documenatation, the syntax for a $near query is different when using a GeoJSON point instead of legacy coordinates. When creating the $geoWithin in CountQuery.createGeoWithin in combination with a GeoJSON point, the $maxDistance cannot be found, as it is nested inside the $near document. With the current implementation, $maxDistance is only detected if it is on the source level (which is the case when legacy coordinates are used):

boolean spheric = source.containsKey("$nearSphere");
Object $near = spheric ? source.get("$nearSphere") : source.get("$near");

Number maxDistance = source.containsKey("$maxDistance") ? (Number) source.get("$maxDistance") : Double.MAX_VALUE;

This results in maxDistance having the value Double.MAX_VALUE (which is 1.7976931348623157E308). When executing the rewritten query against MongoDB, this fails with the error org.springframework.data.mongodb.UncategorizedMongoDbException: Command failed with error 2 (BadValue): 'Point must only contain numeric elements' on server localhost:27017, as it cannot handle the scientific notation (1.7976931348623157E308) of Double.MAX_VALUE. Could someone help with that issue?

sebastian-firsching avatar Mar 22 '22 07:03 sebastian-firsching

Thanks for reaching out could you please take the time to provide a complete minimal sample (something that we can unzip or git clone, build, and deploy) that reproduces the problem.

christophstrobl avatar Mar 22 '22 09:03 christophstrobl

Sure, I have created a quick example that executes a count with a near query and GeoJSON point in an application runner directly after startup. Just make sure, that you have a MongoDB running locally on port 27017. geojson-near-example.zip

sebastian-firsching avatar Mar 22 '22 09:03 sebastian-firsching

Thanks for the reproducer - the rewrite of $near and $nearSphere is missing specific handling for geoJson $geometry which needs to be converted into a legacy coordinate pair for $geowithin $center | $centerSphere. As noted the $maxDistance also is in a different place and needs to extracted from the given source. A bit of extra complexity comes in by $nearSphere using meters in case of geoJson, whereas $centerSphere operates upon radians.

christophstrobl avatar Mar 23 '22 12:03 christophstrobl

Related to: #2925

christophstrobl avatar Mar 23 '22 12:03 christophstrobl