diff --git a/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/aggregation/GeoNearOperation.java b/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/aggregation/GeoNearOperation.java index 29afc03f8..83e18cf3f 100644 --- a/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/aggregation/GeoNearOperation.java +++ b/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/aggregation/GeoNearOperation.java @@ -1,5 +1,5 @@ /* - * Copyright 2013-2015 the original author or authors. + * Copyright 2013-2018 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -17,6 +17,7 @@ package org.springframework.data.mongodb.core.aggregation; import org.springframework.data.mongodb.core.query.NearQuery; import org.springframework.util.Assert; +import org.springframework.util.StringUtils; import com.mongodb.BasicDBObject; import com.mongodb.DBObject; @@ -26,7 +27,7 @@ import com.mongodb.DBObject; *
* We recommend to use the static factory method {@link Aggregation#geoNear(NearQuery, String)} instead of creating
* instances of this class directly.
- *
+ *
* @author Thomas Darimont
* @since 1.3
*/
@@ -34,24 +35,50 @@ public class GeoNearOperation implements AggregationOperation {
private final NearQuery nearQuery;
private final String distanceField;
+ private final String indexKey;
/**
* Creates a new {@link GeoNearOperation} from the given {@link NearQuery} and the given distance field. The
* {@code distanceField} defines output field that contains the calculated distance.
- *
- * @param query must not be {@literal null}.
+ *
+ * @param nearQuery must not be {@literal null}.
* @param distanceField must not be {@literal null}.
*/
public GeoNearOperation(NearQuery nearQuery, String distanceField) {
+ this(nearQuery, distanceField, null);
+ }
+
+ /**
+ * Creates a new {@link GeoNearOperation} from the given {@link NearQuery} and the given distance field. The
+ * {@code distanceField} defines output field that contains the calculated distance.
+ *
+ * @param nearQuery must not be {@literal null}.
+ * @param distanceField must not be {@literal null}.
+ * @param indexKey can be {@literal null};
+ */
+ private GeoNearOperation(NearQuery nearQuery, String distanceField, String indexKey) {
Assert.notNull(nearQuery, "NearQuery must not be null.");
Assert.hasLength(distanceField, "Distance field must not be null or empty.");
this.nearQuery = nearQuery;
this.distanceField = distanceField;
+ this.indexKey = indexKey;
+ }
+
+ /**
+ * Optionally specify the geospatial index to use via the field to use in the calculation.
+ * NOTE: Requires MongoDB 4.0 or later.
+ *
+ * @param key the geospatial index field to use when calculating the distance.
+ * @return new instance of {@link GeoNearOperation}.
+ * @since 2.1
+ */
+ public GeoNearOperation useIndex(String key) {
+ return new GeoNearOperation(nearQuery, distanceField, key);
}
- /*
+ /*
* (non-Javadoc)
* @see org.springframework.data.mongodb.core.aggregation.AggregationOperation#toDBObject(org.springframework.data.mongodb.core.aggregation.AggregationOperationContext)
*/
@@ -61,6 +88,10 @@ public class GeoNearOperation implements AggregationOperation {
BasicDBObject command = (BasicDBObject) context.getMappedObject(nearQuery.toDBObject());
command.put("distanceField", distanceField);
+ if (StringUtils.hasText(indexKey)) {
+ command.put("key", indexKey);
+ }
+
return new BasicDBObject("$geoNear", command);
}
}
diff --git a/spring-data-mongodb/src/test/java/org/springframework/data/mongodb/core/aggregation/GeoNearOperationUnitTests.java b/spring-data-mongodb/src/test/java/org/springframework/data/mongodb/core/aggregation/GeoNearOperationUnitTests.java
index f676ed5a9..12f3ed7ff 100644
--- a/spring-data-mongodb/src/test/java/org/springframework/data/mongodb/core/aggregation/GeoNearOperationUnitTests.java
+++ b/spring-data-mongodb/src/test/java/org/springframework/data/mongodb/core/aggregation/GeoNearOperationUnitTests.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2013-2017 the original author or authors.
+ * Copyright 2013-2018 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -27,9 +27,10 @@ import com.mongodb.DBObject;
/**
* Unit tests for {@link GeoNearOperation}.
- *
+ *
* @author Oliver Gierke
* @author Thomas Darimont
+ * @author Christoph Strobl
*/
public class GeoNearOperationUnitTests {
@@ -42,7 +43,21 @@ public class GeoNearOperationUnitTests {
DBObject nearClause = DBObjectTestUtils.getAsDBObject(dbObject, "$geoNear");
- DBObject expected = (DBObject) new BasicDBObject(query.toDBObject().toMap()).append("distanceField", "distance");
+ DBObject expected = new BasicDBObject(query.toDBObject().toMap()).append("distanceField", "distance");
+ assertThat(nearClause, is(expected));
+ }
+
+ @Test // DATAMONGO-2050
+ public void rendersNearQueryWithKeyCorrectly() {
+
+ NearQuery query = NearQuery.near(10.0, 10.0);
+ GeoNearOperation operation = new GeoNearOperation(query, "distance").useIndex("geo-index-1");
+ DBObject dbObject = operation.toDBObject(Aggregation.DEFAULT_CONTEXT);
+
+ DBObject nearClause = DBObjectTestUtils.getAsDBObject(dbObject, "$geoNear");
+
+ DBObject expected = new BasicDBObject(query.toDBObject().toMap()).append("distanceField", "distance").append("key",
+ "geo-index-1");
assertThat(nearClause, is(expected));
}
}