diff --git a/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/query/MetricConversion.java b/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/query/MetricConversion.java index 72e76b997..f78bb850d 100644 --- a/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/query/MetricConversion.java +++ b/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/query/MetricConversion.java @@ -29,7 +29,7 @@ import org.springframework.data.geo.Metrics; * @author Mark Paluch * @since 2.2 */ -class MetricConversion { +public class MetricConversion { private static final BigDecimal METERS_MULTIPLIER = new BigDecimal(Metrics.KILOMETERS.getMultiplier()) .multiply(new BigDecimal(1000)); @@ -43,7 +43,7 @@ class MetricConversion { * @param metric * @return */ - protected static double getMetersToMetricMultiplier(Metric metric) { + public static double getMetersToMetricMultiplier(Metric metric) { ConversionMultiplier conversionMultiplier = ConversionMultiplier.builder().from(METERS_MULTIPLIER).to(metric) .build(); @@ -56,7 +56,7 @@ class MetricConversion { * @param distance * @return */ - protected static double getDistanceInMeters(Distance distance) { + public static double getDistanceInMeters(Distance distance) { return new BigDecimal(distance.getValue()).multiply(getMetricToMetersMultiplier(distance.getMetric())) .doubleValue(); } diff --git a/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/repository/query/MongoQueryCreator.java b/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/repository/query/MongoQueryCreator.java index ae4499919..d9595ffd3 100644 --- a/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/repository/query/MongoQueryCreator.java +++ b/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/repository/query/MongoQueryCreator.java @@ -36,11 +36,13 @@ import org.springframework.data.geo.Shape; import org.springframework.data.mapping.PersistentPropertyPath; import org.springframework.data.mapping.PropertyPath; import org.springframework.data.mapping.context.MappingContext; +import org.springframework.data.mongodb.core.geo.GeoJson; import org.springframework.data.mongodb.core.index.GeoSpatialIndexType; import org.springframework.data.mongodb.core.index.GeoSpatialIndexed; import org.springframework.data.mongodb.core.mapping.MongoPersistentProperty; import org.springframework.data.mongodb.core.query.Criteria; import org.springframework.data.mongodb.core.query.CriteriaDefinition; +import org.springframework.data.mongodb.core.query.MetricConversion; import org.springframework.data.mongodb.core.query.MongoRegexCreator; import org.springframework.data.mongodb.core.query.MongoRegexCreator.MatchMode; import org.springframework.data.mongodb.core.query.Query; @@ -235,8 +237,14 @@ class MongoQueryCreator extends AbstractQueryCreator { criteria.near(pointToUse); } - criteria.maxDistance(it.getNormalizedValue()); - minDistance.ifPresent(min -> criteria.minDistance(min.getNormalizedValue())); + if(pointToUse instanceof GeoJson) { // using GeoJson distance is in meters. + + criteria.maxDistance(MetricConversion.getDistanceInMeters(it)); + minDistance.map(MetricConversion::getDistanceInMeters).ifPresent(min -> criteria.minDistance(min)); + } else { + criteria.maxDistance(it.getNormalizedValue()); + minDistance.ifPresent(min -> criteria.minDistance(min.getNormalizedValue())); + } return criteria; diff --git a/spring-data-mongodb/src/test/java/org/springframework/data/mongodb/core/convert/QueryMapperUnitTests.java b/spring-data-mongodb/src/test/java/org/springframework/data/mongodb/core/convert/QueryMapperUnitTests.java index d1fd28622..db14d6bc1 100755 --- a/spring-data-mongodb/src/test/java/org/springframework/data/mongodb/core/convert/QueryMapperUnitTests.java +++ b/spring-data-mongodb/src/test/java/org/springframework/data/mongodb/core/convert/QueryMapperUnitTests.java @@ -890,6 +890,17 @@ public class QueryMapperUnitTests { assertThat(target).isEqualTo(new org.bson.Document("_id", "id-1")); } + @Test // DATAMONGO-2394 + public void leavesDistanceUntouchedWhenUsingGeoJson() { + + Query query = query(where("geoJsonPoint").near(new GeoJsonPoint(27.987901, 86.9165379)).maxDistance(1000)); + + org.bson.Document document = mapper.getMappedObject(query.getQueryObject(), + context.getPersistentEntity(ClassWithGeoTypes.class)); + assertThat(document).containsEntry("geoJsonPoint.$near.$geometry.type", "Point"); + assertThat(document).containsEntry("geoJsonPoint.$near.$maxDistance", 1000.0D); + } + @Document public class Foo { @Id private ObjectId id; diff --git a/spring-data-mongodb/src/test/java/org/springframework/data/mongodb/repository/query/MongoQueryCreatorUnitTests.java b/spring-data-mongodb/src/test/java/org/springframework/data/mongodb/repository/query/MongoQueryCreatorUnitTests.java index 327da33a1..3b83348b2 100644 --- a/spring-data-mongodb/src/test/java/org/springframework/data/mongodb/repository/query/MongoQueryCreatorUnitTests.java +++ b/spring-data-mongodb/src/test/java/org/springframework/data/mongodb/repository/query/MongoQueryCreatorUnitTests.java @@ -652,6 +652,17 @@ public class MongoQueryCreatorUnitTests { assertThat(creator.createQuery()).isEqualTo(query(where("age").gt(10).lt(11))); } + @Test // DATAMONGO-2394 + public void nearShouldUseMetricDistanceForGeoJsonTypes() { + + GeoJsonPoint point = new GeoJsonPoint(27.987901, 86.9165379); + PartTree tree = new PartTree("findByLocationNear", User.class); + MongoQueryCreator creator = new MongoQueryCreator(tree, + getAccessor(converter, point, new Distance(1, Metrics.KILOMETERS)), context); + + assertThat(creator.createQuery()).isEqualTo(query(where("location").nearSphere(point).maxDistance(1000.0D))); + } + interface PersonRepository extends Repository { List findByLocationNearAndFirstname(Point location, Distance maxDistance, String firstname);