-
Notifications
You must be signed in to change notification settings - Fork 1.1k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
DATAMONGO-1127 - Add support for geoNear queries with distance information. #261
Changes from 3 commits
d1888e1
a530bc8
00d3da7
018e754
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,5 +1,5 @@ | ||
/* | ||
* Copyright 2013 the original author or authors. | ||
* Copyright 2013-2015 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. | ||
|
@@ -28,11 +28,15 @@ | |
public class GeoNearOperation implements AggregationOperation { | ||
|
||
private final NearQuery nearQuery; | ||
private final String distanceField; | ||
|
||
public GeoNearOperation(NearQuery nearQuery) { | ||
public GeoNearOperation(NearQuery nearQuery, String distanceField) { | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I think we have to overload the constructor to not break existing clients using the old constructor. I suggest to add a hint to favor There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. You're right. Regarding the hint yes thats a good idea I'll add that. |
||
|
||
Assert.notNull(nearQuery); | ||
Assert.notNull(distanceField, "DistanceField must not be null."); | ||
|
||
this.nearQuery = nearQuery; | ||
this.distanceField = distanceField; | ||
} | ||
|
||
/* | ||
|
@@ -41,6 +45,10 @@ public GeoNearOperation(NearQuery nearQuery) { | |
*/ | ||
@Override | ||
public DBObject toDBObject(AggregationOperationContext context) { | ||
return new BasicDBObject("$geoNear", context.getMappedObject(nearQuery.toDBObject())); | ||
|
||
BasicDBObject command = (BasicDBObject) context.getMappedObject(nearQuery.toDBObject()); | ||
command.put("distanceField", distanceField); | ||
|
||
return new BasicDBObject("$geoNear", command); | ||
} | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,5 +1,5 @@ | ||
/* | ||
* Copyright 2013 the original author or authors. | ||
* Copyright 2013-2015 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. | ||
|
@@ -47,11 +47,14 @@ | |
import org.springframework.dao.DataAccessException; | ||
import org.springframework.data.annotation.Id; | ||
import org.springframework.data.domain.Sort.Direction; | ||
import org.springframework.data.geo.Metrics; | ||
import org.springframework.data.mapping.model.MappingException; | ||
import org.springframework.data.mongodb.core.CollectionCallback; | ||
import org.springframework.data.mongodb.core.MongoTemplate; | ||
import org.springframework.data.mongodb.core.Venue; | ||
import org.springframework.data.mongodb.core.aggregation.AggregationTests.CarDescriptor.Entry; | ||
import org.springframework.data.mongodb.core.mapping.Document; | ||
import org.springframework.data.mongodb.core.index.GeospatialIndex; | ||
import org.springframework.data.mongodb.core.query.NearQuery; | ||
import org.springframework.data.mongodb.core.query.Query; | ||
import org.springframework.data.mongodb.repository.Person; | ||
import org.springframework.data.util.Version; | ||
|
@@ -1018,6 +1021,34 @@ public void shouldRetrieveDateTimeFragementsCorrectly() throws Exception { | |
assertThat(dbo.get("dayOfYearPlus1DayManually"), is((Object) dateTime.plusDays(1).getDayOfYear())); | ||
} | ||
|
||
/** | ||
* @see DATAMONGO-1127 | ||
*/ | ||
@Test | ||
public void shouldSupportGeoNearQueriesForAggregation() { | ||
|
||
mongoTemplate.dropCollection(Venue.class); | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. We should handle these cleanup operations in JUnit callback methods (the same for the drop of the collection at the very end) to make sure they get applied even if exceptions occur. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. ack |
||
|
||
mongoTemplate.insert(new Venue("Penn Station", -73.99408, 40.75057)); | ||
mongoTemplate.insert(new Venue("10gen Office", -73.99171, 40.738868)); | ||
mongoTemplate.insert(new Venue("Flatiron Building", -73.988135, 40.741404)); | ||
|
||
mongoTemplate.indexOps(Venue.class).ensureIndex(new GeospatialIndex("location")); | ||
|
||
NearQuery geoNear = NearQuery.near(-73, 40, Metrics.KILOMETERS).num(10).maxDistance(150); | ||
|
||
Aggregation agg = newAggregation(Aggregation.geoNear(geoNear, "distance")); | ||
AggregationResults<DBObject> result = mongoTemplate.aggregate(agg, Venue.class, DBObject.class); | ||
|
||
assertThat(result.getMappedResults(), hasSize(3)); | ||
|
||
DBObject firstResult = result.getMappedResults().get(0); | ||
assertThat(firstResult.containsField("distance"), is(true)); | ||
assertThat(firstResult.get("distance"), is((Object) 117.620092203928)); | ||
|
||
mongoTemplate.dropCollection(Venue.class); | ||
} | ||
|
||
private void assertLikeStats(LikeStats like, String id, long count) { | ||
|
||
assertThat(like, is(notNullValue())); | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Should we actually add an overload without the distance field applied so that basically people can mimic what they got when using
new GeoNearOperation(nearQuery)
before?There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
the geoNear(...) method was not exposed before this PR.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I see that. Still, we need to keep the constructor in
GeoNearOperations
which then raises the question whygeoNear(query, distance)
is available as factory method butgeoNear(query)
is not. We should stay symmetric here.There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Ack.