DATAMONGO-1674 - Adapted to Range API changes.

This commit is contained in:
Oliver Gierke
2017-04-26 17:32:27 +02:00
parent 9ae3a29103
commit e01c745884
7 changed files with 94 additions and 94 deletions

View File

@@ -0,0 +1,48 @@
/*
* Copyright 2017 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.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.springframework.data.mongodb.core.aggregation;
import java.util.ArrayList;
import java.util.List;
import org.springframework.data.domain.Range;
import org.springframework.util.Assert;
/**
* Utility methods for aggregation ooperation implementations.
*
* @author Oliver Gierke
*/
interface AggregationUtils {
/**
* Converts the given {@link Range} into an array of values.
*
* @param range must not be {@literal null}.
* @return
*/
public static List<Long> toRangeValues(Range<Long> range) {
Assert.notNull(range, "Range must not be null!");
List<Long> result = new ArrayList<Long>(2);
result.add(range.getLowerBound().getValue()
.orElseThrow(() -> new IllegalArgumentException("Lower bound of range must be bounded!")));
range.getUpperBound().getValue().ifPresent(it -> result.add(it));
return result;
}
}

View File

@@ -849,16 +849,7 @@ public class ArrayOperators {
}
public IndexOfArray within(Range<Long> range) {
Assert.notNull(range, "Range must not be null!");
List<Long> rangeValues = new ArrayList<Long>(2);
rangeValues.add(range.getLowerBound());
if (range.getUpperBound() != null) {
rangeValues.add(range.getUpperBound());
}
return new IndexOfArray(append(rangeValues));
return new IndexOfArray(append(AggregationUtils.toRangeValues(range)));
}
/**

View File

@@ -15,7 +15,6 @@
*/
package org.springframework.data.mongodb.core.aggregation;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.List;
@@ -732,16 +731,7 @@ public class StringOperators {
* @return
*/
public IndexOfBytes within(Range<Long> range) {
Assert.notNull(range, "Range must not be null!");
List<Long> rangeValues = new ArrayList<Long>(2);
rangeValues.add(range.getLowerBound());
if (range.getUpperBound() != null) {
rangeValues.add(range.getUpperBound());
}
return new IndexOfBytes(append(rangeValues));
return new IndexOfBytes(append(AggregationUtils.toRangeValues(range)));
}
public static class SubstringBuilder {
@@ -831,16 +821,7 @@ public class StringOperators {
* @return
*/
public IndexOfCP within(Range<Long> range) {
Assert.notNull(range, "Range must not be null!");
List<Long> rangeValues = new ArrayList<Long>(2);
rangeValues.add(range.getLowerBound());
if (range.getUpperBound() != null) {
rangeValues.add(range.getUpperBound());
}
return new IndexOfCP(append(rangeValues));
return new IndexOfCP(append(AggregationUtils.toRangeValues(range)));
}
public static class SubstringBuilder {

View File

@@ -21,7 +21,6 @@ import java.util.Arrays;
import java.util.Collection;
import java.util.Iterator;
import java.util.Optional;
import java.util.regex.Pattern;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
@@ -61,7 +60,6 @@ import org.springframework.util.ClassUtils;
class MongoQueryCreator extends AbstractQueryCreator<Query, Criteria> {
private static final Logger LOG = LoggerFactory.getLogger(MongoQueryCreator.class);
private static final Pattern PUNCTATION_PATTERN = Pattern.compile("\\p{Punct}");
private final MongoParameterAccessor accessor;
private final boolean isGeoNearQuery;
@@ -217,28 +215,29 @@ class MongoQueryCreator extends AbstractQueryCreator<Query, Criteria> {
case NEAR:
Range<Distance> range = accessor.getDistanceRange();
Distance distance = range.getUpperBound();
Distance minDistance = range.getLowerBound();
Optional<Distance> distance = range.getUpperBound().getValue();
Optional<Distance> minDistance = range.getLowerBound().getValue();
Point point = accessor.getGeoNearLocation();
point = point == null ? nextAs(parameters, Point.class) : point;
Point pointToUse = point == null ? nextAs(parameters, Point.class) : point;
boolean isSpherical = isSpherical(property);
if (distance == null) {
return isSpherical ? criteria.nearSphere(point) : criteria.near(point);
} else {
if (isSpherical || !Metrics.NEUTRAL.equals(distance.getMetric())) {
criteria.nearSphere(point);
return distance.map(it -> {
if (isSpherical || !Metrics.NEUTRAL.equals(it.getMetric())) {
criteria.nearSphere(pointToUse);
} else {
criteria.near(point);
criteria.near(pointToUse);
}
criteria.maxDistance(distance.getNormalizedValue());
if (minDistance != null) {
criteria.minDistance(minDistance.getNormalizedValue());
}
}
return criteria;
criteria.maxDistance(it.getNormalizedValue());
minDistance.ifPresent(min -> criteria.minDistance(min.getNormalizedValue()));
return criteria;
}).orElseGet(() -> isSpherical ? criteria.nearSphere(pointToUse) : criteria.near(pointToUse));
case WITHIN:
Object parameter = parameters.next();

View File

@@ -140,13 +140,13 @@ interface MongoQueryExecution {
// Adjust limit if page would exceed the overall limit
if (overallLimit != 0 && pageable.getOffset() + pageable.getPageSize() > overallLimit) {
query.limit((int)(overallLimit - pageable.getOffset()));
query.limit((int) (overallLimit - pageable.getOffset()));
}
return PageableExecutionUtils.getPage(operations.find(query, type, collection), pageable, () -> {
long count = operations.count(query, type, collection);
return overallLimit != 0 ? Math.min(count, overallLimit) : count;
long count = operations.count(query, type, collection);
return overallLimit != 0 ? Math.min(count, overallLimit) : count;
});
}
@@ -249,17 +249,8 @@ interface MongoQueryExecution {
}
Range<Distance> distances = accessor.getDistanceRange();
Distance maxDistance = distances.getUpperBound();
if (maxDistance != null) {
nearQuery.maxDistance(maxDistance).in(maxDistance.getMetric());
}
Distance minDistance = distances.getLowerBound();
if (minDistance != null) {
nearQuery.minDistance(minDistance).in(minDistance.getMetric());
}
distances.getLowerBound().getValue().ifPresent(it -> nearQuery.minDistance(it).in(it.getMetric()));
distances.getUpperBound().getValue().ifPresent(it -> nearQuery.maxDistance(it).in(it.getMetric()));
Pageable pageable = accessor.getPageable();
@@ -315,13 +306,12 @@ interface MongoQueryExecution {
Page<GeoResult<Object>> page = PageableExecutionUtils.getPage(geoResults.getContent(), accessor.getPageable(),
() -> {
ConvertingParameterAccessor parameterAccessor = new ConvertingParameterAccessor(operations.getConverter(),
accessor);
Query countQuery = mongoQuery
.applyQueryMetaAttributesWhenPresent(mongoQuery.createCountQuery(parameterAccessor));
ConvertingParameterAccessor parameterAccessor = new ConvertingParameterAccessor(operations.getConverter(),
accessor);
Query countQuery = mongoQuery
.applyQueryMetaAttributesWhenPresent(mongoQuery.createCountQuery(parameterAccessor));
return operations.count(countQuery, collection);
return operations.count(countQuery, collection);
});

View File

@@ -15,13 +15,16 @@
*/
package org.springframework.data.mongodb.repository.query;
import lombok.NonNull;
import lombok.RequiredArgsConstructor;
import reactor.core.publisher.Flux;
import java.util.Optional;
import org.springframework.core.convert.converter.Converter;
import org.springframework.data.convert.EntityInstantiators;
import org.springframework.data.domain.Pageable;
import org.springframework.data.domain.Range;
import org.springframework.data.domain.Slice;
import org.springframework.data.geo.Distance;
import org.springframework.data.geo.GeoResult;
import org.springframework.data.geo.Point;
@@ -34,17 +37,12 @@ import org.springframework.data.repository.util.ReactiveWrappers;
import org.springframework.data.util.TypeInformation;
import org.springframework.util.ClassUtils;
import lombok.NonNull;
import lombok.RequiredArgsConstructor;
import reactor.core.publisher.Flux;
import reactor.core.publisher.Mono;
import com.mongodb.client.result.DeleteResult;
/**
* Set of classes to contain query execution strategies. Depending (mostly) on the return type of a
* {@link org.springframework.data.repository.query.QueryMethod} a {@link AbstractReactiveMongoQuery} can be executed in various
* flavors.
* {@link org.springframework.data.repository.query.QueryMethod} a {@link AbstractReactiveMongoQuery} can be executed in
* various flavors.
*
* @author Mark Paluch
* @since 2.0
@@ -127,7 +125,7 @@ interface ReactiveMongoQueryExecution {
return isStreamOfGeoResult() ? results : results.map(GeoResult::getContent);
}
@SuppressWarnings("unchecked")
@SuppressWarnings({ "unchecked", "rawtypes" })
protected Flux<GeoResult<Object>> doExecuteQuery(Query query, Class<?> type, String collection) {
Point nearLocation = accessor.getGeoNearLocation();
@@ -138,17 +136,8 @@ interface ReactiveMongoQueryExecution {
}
Range<Distance> distances = accessor.getDistanceRange();
Distance maxDistance = distances.getUpperBound();
if (maxDistance != null) {
nearQuery.maxDistance(maxDistance).in(maxDistance.getMetric());
}
Distance minDistance = distances.getLowerBound();
if (minDistance != null) {
nearQuery.minDistance(minDistance).in(minDistance.getMetric());
}
distances.getUpperBound().getValue().ifPresent(it -> nearQuery.maxDistance(it).in(it.getMetric()));
distances.getLowerBound().getValue().ifPresent(it -> nearQuery.minDistance(it).in(it.getMetric()));
Pageable pageable = accessor.getPageable();

View File

@@ -15,8 +15,9 @@
*/
package org.springframework.data.mongodb.repository.query;
import static org.assertj.core.api.Assertions.assertThat;
import static org.hamcrest.CoreMatchers.*;
import static org.junit.Assert.*;
import static org.junit.Assert.assertThat;
import java.lang.reflect.Method;
import java.util.List;
@@ -25,6 +26,7 @@ import org.bson.Document;
import org.hamcrest.core.IsNull;
import org.junit.Test;
import org.springframework.data.domain.Range;
import org.springframework.data.domain.Range.Bound;
import org.springframework.data.geo.Distance;
import org.springframework.data.geo.Metrics;
import org.springframework.data.geo.Point;
@@ -51,14 +53,14 @@ public class MongoParametersParameterAccessorUnitTests {
ProjectionFactory factory = new SpelAwareProxyProjectionFactory();
@Test
public void returnsNullForDistanceIfNoneAvailable() throws NoSuchMethodException, SecurityException {
public void returnsUnboundedForDistanceIfNoneAvailable() throws NoSuchMethodException, SecurityException {
Method method = PersonRepository.class.getMethod("findByLocationNear", Point.class);
MongoQueryMethod queryMethod = new MongoQueryMethod(method, metadata, factory, context);
MongoParameterAccessor accessor = new MongoParametersParameterAccessor(queryMethod,
new Object[] { new Point(10, 20) });
assertThat(accessor.getDistanceRange().getUpperBound(), is(nullValue()));
assertThat(accessor.getDistanceRange().getUpperBound().isBounded()).isFalse();
}
@Test
@@ -69,7 +71,7 @@ public class MongoParametersParameterAccessorUnitTests {
MongoParameterAccessor accessor = new MongoParametersParameterAccessor(queryMethod,
new Object[] { new Point(10, 20), DISTANCE });
assertThat(accessor.getDistanceRange().getUpperBound(), is(DISTANCE));
assertThat(accessor.getDistanceRange().getUpperBound()).isEqualTo(Bound.inclusive(DISTANCE));
}
@Test // DATAMONGO-973
@@ -109,8 +111,8 @@ public class MongoParametersParameterAccessorUnitTests {
Range<Distance> range = accessor.getDistanceRange();
assertThat(range.getLowerBound(), is(min));
assertThat(range.getUpperBound(), is(max));
assertThat(range.getLowerBound(), is(Bound.inclusive(min)));
assertThat(range.getUpperBound(), is(Bound.inclusive(max)));
}
interface PersonRepository extends Repository<Person, Long> {