DATAMONGO-1674 - Adapted to Range API changes.
This commit is contained in:
@@ -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;
|
||||
}
|
||||
}
|
||||
@@ -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)));
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -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 {
|
||||
|
||||
@@ -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();
|
||||
|
||||
@@ -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);
|
||||
|
||||
});
|
||||
|
||||
|
||||
@@ -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();
|
||||
|
||||
|
||||
@@ -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> {
|
||||
|
||||
Reference in New Issue
Block a user