DATAMONGO-2050 - Allow to specify the index to use for $geoNear aggregation operation.
Original pull request: #596.
This commit is contained in:
committed by
Mark Paluch
parent
e484337dcf
commit
cd089d4a54
@@ -17,7 +17,9 @@ package org.springframework.data.mongodb.core.aggregation;
|
|||||||
|
|
||||||
import org.bson.Document;
|
import org.bson.Document;
|
||||||
import org.springframework.data.mongodb.core.query.NearQuery;
|
import org.springframework.data.mongodb.core.query.NearQuery;
|
||||||
|
import org.springframework.lang.Nullable;
|
||||||
import org.springframework.util.Assert;
|
import org.springframework.util.Assert;
|
||||||
|
import org.springframework.util.StringUtils;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Represents a {@code geoNear} aggregation operation.
|
* Represents a {@code geoNear} aggregation operation.
|
||||||
@@ -33,21 +35,47 @@ public class GeoNearOperation implements AggregationOperation {
|
|||||||
|
|
||||||
private final NearQuery nearQuery;
|
private final NearQuery nearQuery;
|
||||||
private final String distanceField;
|
private final String distanceField;
|
||||||
|
private final @Nullable String indexKey;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Creates a new {@link GeoNearOperation} from the given {@link NearQuery} and the given distance field. The
|
* 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.
|
* {@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}.
|
* @param distanceField must not be {@literal null}.
|
||||||
*/
|
*/
|
||||||
public GeoNearOperation(NearQuery nearQuery, String distanceField) {
|
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, @Nullable String indexKey) {
|
||||||
|
|
||||||
Assert.notNull(nearQuery, "NearQuery must not be null.");
|
Assert.notNull(nearQuery, "NearQuery must not be null.");
|
||||||
Assert.hasLength(distanceField, "Distance field must not be null or empty.");
|
Assert.hasLength(distanceField, "Distance field must not be null or empty.");
|
||||||
|
|
||||||
this.nearQuery = nearQuery;
|
this.nearQuery = nearQuery;
|
||||||
this.distanceField = distanceField;
|
this.distanceField = distanceField;
|
||||||
|
this.indexKey = indexKey;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Optionally specify the geospatial index to use via the field to use in the calculation. <br />
|
||||||
|
* <strong>NOTE:</strong> 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);
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@@ -60,6 +88,10 @@ public class GeoNearOperation implements AggregationOperation {
|
|||||||
Document command = context.getMappedObject(nearQuery.toDocument());
|
Document command = context.getMappedObject(nearQuery.toDocument());
|
||||||
command.put("distanceField", distanceField);
|
command.put("distanceField", distanceField);
|
||||||
|
|
||||||
|
if (StringUtils.hasText(indexKey)) {
|
||||||
|
command.put("key", indexKey);
|
||||||
|
}
|
||||||
|
|
||||||
return new Document("$geoNear", command);
|
return new Document("$geoNear", command);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -28,6 +28,7 @@ import org.springframework.data.mongodb.core.query.NearQuery;
|
|||||||
*
|
*
|
||||||
* @author Oliver Gierke
|
* @author Oliver Gierke
|
||||||
* @author Thomas Darimont
|
* @author Thomas Darimont
|
||||||
|
* @author Christoph Strobl
|
||||||
*/
|
*/
|
||||||
public class GeoNearOperationUnitTests {
|
public class GeoNearOperationUnitTests {
|
||||||
|
|
||||||
@@ -43,4 +44,17 @@ public class GeoNearOperationUnitTests {
|
|||||||
Document expected = new Document(query.toDocument()).append("distanceField", "distance");
|
Document expected = new Document(query.toDocument()).append("distanceField", "distance");
|
||||||
assertThat(nearClause, is(expected));
|
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");
|
||||||
|
Document document = operation.toDocument(Aggregation.DEFAULT_CONTEXT);
|
||||||
|
|
||||||
|
Document nearClause = DocumentTestUtils.getAsDocument(document, "$geoNear");
|
||||||
|
|
||||||
|
Document expected = new Document(query.toDocument()).append("distanceField", "distance").append("key", "geo-index-1");
|
||||||
|
assertThat(nearClause, is(expected));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user