Skip to content

Commit 9faeb1a

Browse files
christophstroblmp911de
authored andcommitted
DATAMONGO-2050 - Allow to specify the index to use for $geoNear aggregation operation.
Original pull request: #596.
1 parent bbc7a64 commit 9faeb1a

File tree

2 files changed

+54
-8
lines changed

2 files changed

+54
-8
lines changed

spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/aggregation/GeoNearOperation.java

Lines changed: 36 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright 2013-2015 the original author or authors.
2+
* Copyright 2013-2018 the original author or authors.
33
*
44
* Licensed under the Apache License, Version 2.0 (the "License");
55
* you may not use this file except in compliance with the License.
@@ -17,6 +17,7 @@
1717

1818
import org.springframework.data.mongodb.core.query.NearQuery;
1919
import org.springframework.util.Assert;
20+
import org.springframework.util.StringUtils;
2021

2122
import com.mongodb.BasicDBObject;
2223
import com.mongodb.DBObject;
@@ -26,32 +27,58 @@
2627
* <p>
2728
* We recommend to use the static factory method {@link Aggregation#geoNear(NearQuery, String)} instead of creating
2829
* instances of this class directly.
29-
*
30+
*
3031
* @author Thomas Darimont
3132
* @since 1.3
3233
*/
3334
public class GeoNearOperation implements AggregationOperation {
3435

3536
private final NearQuery nearQuery;
3637
private final String distanceField;
38+
private final String indexKey;
3739

3840
/**
3941
* Creates a new {@link GeoNearOperation} from the given {@link NearQuery} and the given distance field. The
4042
* {@code distanceField} defines output field that contains the calculated distance.
41-
*
42-
* @param query must not be {@literal null}.
43+
*
44+
* @param nearQuery must not be {@literal null}.
4345
* @param distanceField must not be {@literal null}.
4446
*/
4547
public GeoNearOperation(NearQuery nearQuery, String distanceField) {
48+
this(nearQuery, distanceField, null);
49+
}
50+
51+
/**
52+
* Creates a new {@link GeoNearOperation} from the given {@link NearQuery} and the given distance field. The
53+
* {@code distanceField} defines output field that contains the calculated distance.
54+
*
55+
* @param nearQuery must not be {@literal null}.
56+
* @param distanceField must not be {@literal null}.
57+
* @param indexKey can be {@literal null};
58+
*/
59+
private GeoNearOperation(NearQuery nearQuery, String distanceField, String indexKey) {
4660

4761
Assert.notNull(nearQuery, "NearQuery must not be null.");
4862
Assert.hasLength(distanceField, "Distance field must not be null or empty.");
4963

5064
this.nearQuery = nearQuery;
5165
this.distanceField = distanceField;
66+
this.indexKey = indexKey;
67+
}
68+
69+
/**
70+
* Optionally specify the geospatial index to use via the field to use in the calculation. <br />
71+
* <strong>NOTE:</strong> Requires MongoDB 4.0 or later.
72+
*
73+
* @param key the geospatial index field to use when calculating the distance.
74+
* @return new instance of {@link GeoNearOperation}.
75+
* @since 2.1
76+
*/
77+
public GeoNearOperation useIndex(String key) {
78+
return new GeoNearOperation(nearQuery, distanceField, key);
5279
}
5380

54-
/*
81+
/*
5582
* (non-Javadoc)
5683
* @see org.springframework.data.mongodb.core.aggregation.AggregationOperation#toDBObject(org.springframework.data.mongodb.core.aggregation.AggregationOperationContext)
5784
*/
@@ -61,6 +88,10 @@ public DBObject toDBObject(AggregationOperationContext context) {
6188
BasicDBObject command = (BasicDBObject) context.getMappedObject(nearQuery.toDBObject());
6289
command.put("distanceField", distanceField);
6390

91+
if (StringUtils.hasText(indexKey)) {
92+
command.put("key", indexKey);
93+
}
94+
6495
return new BasicDBObject("$geoNear", command);
6596
}
6697
}

spring-data-mongodb/src/test/java/org/springframework/data/mongodb/core/aggregation/GeoNearOperationUnitTests.java

Lines changed: 18 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright 2013-2017 the original author or authors.
2+
* Copyright 2013-2018 the original author or authors.
33
*
44
* Licensed under the Apache License, Version 2.0 (the "License");
55
* you may not use this file except in compliance with the License.
@@ -27,9 +27,10 @@
2727

2828
/**
2929
* Unit tests for {@link GeoNearOperation}.
30-
*
30+
*
3131
* @author Oliver Gierke
3232
* @author Thomas Darimont
33+
* @author Christoph Strobl
3334
*/
3435
public class GeoNearOperationUnitTests {
3536

@@ -42,7 +43,21 @@ public void rendersNearQueryAsAggregationOperation() {
4243

4344
DBObject nearClause = DBObjectTestUtils.getAsDBObject(dbObject, "$geoNear");
4445

45-
DBObject expected = (DBObject) new BasicDBObject(query.toDBObject().toMap()).append("distanceField", "distance");
46+
DBObject expected = new BasicDBObject(query.toDBObject().toMap()).append("distanceField", "distance");
47+
assertThat(nearClause, is(expected));
48+
}
49+
50+
@Test // DATAMONGO-2050
51+
public void rendersNearQueryWithKeyCorrectly() {
52+
53+
NearQuery query = NearQuery.near(10.0, 10.0);
54+
GeoNearOperation operation = new GeoNearOperation(query, "distance").useIndex("geo-index-1");
55+
DBObject dbObject = operation.toDBObject(Aggregation.DEFAULT_CONTEXT);
56+
57+
DBObject nearClause = DBObjectTestUtils.getAsDBObject(dbObject, "$geoNear");
58+
59+
DBObject expected = new BasicDBObject(query.toDBObject().toMap()).append("distanceField", "distance").append("key",
60+
"geo-index-1");
4661
assertThat(nearClause, is(expected));
4762
}
4863
}

0 commit comments

Comments
 (0)