use of org.springframework.data.geo.GeoResults in project spring-data-mongodb by spring-projects.
the class MongoTemplate method geoNear.
public <T> GeoResults<T> geoNear(NearQuery near, Class<?> domainType, String collectionName, Class<T> returnType) {
if (near == null) {
throw new InvalidDataAccessApiUsageException("NearQuery must not be null!");
}
if (domainType == null) {
throw new InvalidDataAccessApiUsageException("Entity class must not be null!");
}
Assert.notNull(collectionName, "CollectionName must not be null!");
Assert.notNull(returnType, "ReturnType must not be null!");
String collection = StringUtils.hasText(collectionName) ? collectionName : getCollectionName(domainType);
String distanceField = operations.nearQueryDistanceFieldName(domainType);
Aggregation $geoNear = TypedAggregation.newAggregation(domainType, Aggregation.geoNear(near, distanceField)).withOptions(AggregationOptions.builder().collation(near.getCollation()).build());
AggregationResults<Document> results = aggregate($geoNear, collection, Document.class);
EntityProjection<T, ?> projection = operations.introspectProjection(returnType, domainType);
DocumentCallback<GeoResult<T>> callback = new GeoNearResultDocumentCallback<>(distanceField, new ProjectingReadCallback<>(mongoConverter, projection, collection), near.getMetric());
List<GeoResult<T>> result = new ArrayList<>();
BigDecimal aggregate = BigDecimal.ZERO;
for (Document element : results) {
GeoResult<T> geoResult = callback.doWith(element);
aggregate = aggregate.add(BigDecimal.valueOf(geoResult.getDistance().getValue()));
result.add(geoResult);
}
Distance avgDistance = new Distance(result.size() == 0 ? 0 : aggregate.divide(new BigDecimal(result.size()), RoundingMode.HALF_UP).doubleValue(), near.getMetric());
return new GeoResults<>(result, avgDistance);
}
Aggregations