DATAMONGO-1986 - Always provide a typed AggregationOperationContext for TypedAggregation.
We now initialize a TypeBasedAggregationOperationContext for TypedAggregations if no context is provided. This makes sure that potential Criteria objects are run trough the QueryMapper. In case the default context is used we now also make sure to at least run the aggregation pipeline through the QueryMapper to avoid passing on non MongoDB simple types to the driver. Original pull request: #564.
This commit is contained in:
committed by
Mark Paluch
parent
daae696c78
commit
2bac54c70f
@@ -218,7 +218,7 @@ public class MongoTemplate implements MongoOperations, ApplicationContextAware,
|
||||
public MongoTemplate(MongoClient mongoClient, String databaseName) {
|
||||
this(new SimpleMongoDbFactory(mongoClient, databaseName), (MongoConverter) null);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Constructor used for a basic template configuration.
|
||||
*
|
||||
@@ -2116,9 +2116,7 @@ public class MongoTemplate implements MongoOperations, ApplicationContextAware,
|
||||
Assert.notNull(aggregation, "Aggregation pipeline must not be null!");
|
||||
Assert.notNull(outputType, "Output type must not be null!");
|
||||
|
||||
AggregationOperationContext rootContext = context == null ? Aggregation.DEFAULT_CONTEXT : context;
|
||||
|
||||
return doAggregate(aggregation, collectionName, outputType, rootContext);
|
||||
return doAggregate(aggregation, collectionName, outputType, prepareAggregationContext(aggregation, context));
|
||||
}
|
||||
|
||||
@SuppressWarnings("ConstantConditions")
|
||||
@@ -2128,9 +2126,10 @@ public class MongoTemplate implements MongoOperations, ApplicationContextAware,
|
||||
DocumentCallback<O> callback = new UnwrapAndReadDocumentCallback<>(mongoConverter, outputType, collectionName);
|
||||
|
||||
AggregationOptions options = aggregation.getOptions();
|
||||
|
||||
if (options.isExplain()) {
|
||||
|
||||
Document command = aggregation.toDocument(collectionName, context);
|
||||
Document command = aggregationToCommand(collectionName, aggregation, context);
|
||||
|
||||
if (LOGGER.isDebugEnabled()) {
|
||||
LOGGER.debug("Executing aggregation: {}", serializeToJsonSafely(command));
|
||||
@@ -2141,7 +2140,7 @@ public class MongoTemplate implements MongoOperations, ApplicationContextAware,
|
||||
.map(callback::doWith).collect(Collectors.toList()), commandResult);
|
||||
}
|
||||
|
||||
List<Document> pipeline = aggregation.toPipeline(context);
|
||||
List<Document> pipeline = aggregationToPipeline(aggregation, context);
|
||||
|
||||
if (LOGGER.isDebugEnabled()) {
|
||||
LOGGER.debug("Executing aggregation: {} in collection {}", serializeToJsonSafely(pipeline), collectionName);
|
||||
@@ -2179,9 +2178,10 @@ public class MongoTemplate implements MongoOperations, ApplicationContextAware,
|
||||
Assert.notNull(outputType, "Output type must not be null!");
|
||||
Assert.isTrue(!aggregation.getOptions().isExplain(), "Can't use explain option with streaming!");
|
||||
|
||||
AggregationOperationContext rootContext = context == null ? Aggregation.DEFAULT_CONTEXT : context;
|
||||
AggregationOperationContext rootContext = prepareAggregationContext(aggregation, context);
|
||||
|
||||
AggregationOptions options = aggregation.getOptions();
|
||||
List<Document> pipeline = aggregation.toPipeline(rootContext);
|
||||
List<Document> pipeline = aggregationToPipeline(aggregation, rootContext);
|
||||
|
||||
if (LOGGER.isDebugEnabled()) {
|
||||
LOGGER.debug("Streaming aggregation: {} in collection {}", serializeToJsonSafely(pipeline), collectionName);
|
||||
@@ -2844,6 +2844,73 @@ public class MongoTemplate implements MongoOperations, ApplicationContextAware,
|
||||
return fields;
|
||||
}
|
||||
|
||||
/**
|
||||
* Prepare the {@link AggregationOperationContext} for a given aggregation by either returning the context itself it
|
||||
* is not {@literal null}, create a {@link TypeBasedAggregationOperationContext} if the aggregation contains type
|
||||
* information (is a {@link TypedAggregation}) or use the {@link Aggregation#DEFAULT_CONTEXT}.
|
||||
*
|
||||
* @param aggregation must not be {@literal null}.
|
||||
* @param context can be {@literal null}.
|
||||
* @return the root {@link AggregationOperationContext} to use.
|
||||
*/
|
||||
private AggregationOperationContext prepareAggregationContext(Aggregation aggregation,
|
||||
@Nullable AggregationOperationContext context) {
|
||||
|
||||
if (context != null) {
|
||||
return context;
|
||||
}
|
||||
|
||||
if (aggregation instanceof TypedAggregation) {
|
||||
return new TypeBasedAggregationOperationContext(((TypedAggregation) aggregation).getInputType(), mappingContext,
|
||||
queryMapper);
|
||||
}
|
||||
|
||||
return Aggregation.DEFAULT_CONTEXT;
|
||||
}
|
||||
|
||||
/**
|
||||
* Extract and map the aggregation pipeline.
|
||||
*
|
||||
* @param aggregation
|
||||
* @param context
|
||||
* @return
|
||||
*/
|
||||
private List<Document> aggregationToPipeline(Aggregation aggregation, AggregationOperationContext context) {
|
||||
|
||||
if (!ObjectUtils.nullSafeEquals(context, Aggregation.DEFAULT_CONTEXT)) {
|
||||
return aggregation.toPipeline(context);
|
||||
}
|
||||
|
||||
return mapAggregationPipeline(aggregation.toPipeline(context));
|
||||
}
|
||||
|
||||
/**
|
||||
* Extract the command and map the aggregation pipeline.
|
||||
*
|
||||
* @param aggregation
|
||||
* @param context
|
||||
* @return
|
||||
*/
|
||||
private Document aggregationToCommand(String collection, Aggregation aggregation,
|
||||
AggregationOperationContext context) {
|
||||
|
||||
Document command = aggregation.toDocument(collection, context);
|
||||
|
||||
if (!ObjectUtils.nullSafeEquals(context, Aggregation.DEFAULT_CONTEXT)) {
|
||||
return command;
|
||||
}
|
||||
|
||||
command.put("pipeline", mapAggregationPipeline(command.get("pipeline", List.class)));
|
||||
|
||||
return command;
|
||||
}
|
||||
|
||||
private List<Document> mapAggregationPipeline(List<Document> pipeline) {
|
||||
|
||||
return pipeline.stream().map(val -> queryMapper.getMappedObject(val, Optional.empty()))
|
||||
.collect(Collectors.toList());
|
||||
}
|
||||
|
||||
/**
|
||||
* Tries to convert the given {@link RuntimeException} into a {@link DataAccessException} but returns the original
|
||||
* exception if the conversation failed. Thus allows safe re-throwing of the return value.
|
||||
|
||||
@@ -496,8 +496,8 @@ public class ReactiveMongoTemplate implements ReactiveMongoOperations, Applicati
|
||||
*/
|
||||
@Override
|
||||
public ReactiveSessionScoped inTransaction() {
|
||||
return inTransaction(mongoDatabaseFactory
|
||||
.getSession(ClientSessionOptions.builder().causallyConsistent(true).build()));
|
||||
return inTransaction(
|
||||
mongoDatabaseFactory.getSession(ClientSessionOptions.builder().causallyConsistent(true).build()));
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -969,9 +969,10 @@ public class ReactiveMongoTemplate implements ReactiveMongoOperations, Applicati
|
||||
Assert.hasText(collectionName, "Collection name must not be null or empty!");
|
||||
Assert.notNull(outputType, "Output type must not be null!");
|
||||
|
||||
AggregationOperationContext rootContext = context == null ? Aggregation.DEFAULT_CONTEXT : context;
|
||||
AggregationOperationContext rootContext = prepareAggregationContext(aggregation, context);
|
||||
|
||||
AggregationOptions options = aggregation.getOptions();
|
||||
List<Document> pipeline = aggregation.toPipeline(rootContext);
|
||||
List<Document> pipeline = aggregationToPipeline(aggregation, rootContext);
|
||||
|
||||
Assert.isTrue(!options.isExplain(), "Cannot use explain option with streaming!");
|
||||
Assert.isNull(options.getCursorBatchSize(), "Cannot use batchSize cursor option with streaming!");
|
||||
@@ -988,7 +989,7 @@ public class ReactiveMongoTemplate implements ReactiveMongoOperations, Applicati
|
||||
AggregationOptions options, ReadDocumentCallback<O> readCallback) {
|
||||
|
||||
AggregatePublisher<Document> cursor = collection.aggregate(pipeline, Document.class)
|
||||
.allowDiskUse(options.isAllowDiskUse()).useCursor(true);
|
||||
.allowDiskUse(options.isAllowDiskUse());
|
||||
|
||||
if (options.getCollation().isPresent()) {
|
||||
cursor = cursor.collation(options.getCollation().map(Collation::toMongoCollation).get());
|
||||
@@ -2653,6 +2654,47 @@ public class ReactiveMongoTemplate implements ReactiveMongoOperations, Applicati
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
* Prepare the {@link AggregationOperationContext} for a given aggregation by either returning the context itself it
|
||||
* is not {@literal null}, create a {@link TypeBasedAggregationOperationContext} if the aggregation contains type
|
||||
* information (is a {@link TypedAggregation}) or use the {@link Aggregation#DEFAULT_CONTEXT}.
|
||||
*
|
||||
* @param aggregation must not be {@literal null}.
|
||||
* @param context can be {@literal null}.
|
||||
* @return the root {@link AggregationOperationContext} to use.
|
||||
*/
|
||||
private AggregationOperationContext prepareAggregationContext(Aggregation aggregation,
|
||||
@Nullable AggregationOperationContext context) {
|
||||
|
||||
if (context != null) {
|
||||
return context;
|
||||
}
|
||||
|
||||
if (aggregation instanceof TypedAggregation) {
|
||||
return new TypeBasedAggregationOperationContext(((TypedAggregation) aggregation).getInputType(), mappingContext,
|
||||
queryMapper);
|
||||
}
|
||||
|
||||
return Aggregation.DEFAULT_CONTEXT;
|
||||
}
|
||||
|
||||
/**
|
||||
* Extract and map the aggregation pipeline.
|
||||
*
|
||||
* @param aggregation
|
||||
* @param context
|
||||
* @return
|
||||
*/
|
||||
private List<Document> aggregationToPipeline(Aggregation aggregation, AggregationOperationContext context) {
|
||||
|
||||
if (!ObjectUtils.nullSafeEquals(context, Aggregation.DEFAULT_CONTEXT)) {
|
||||
return aggregation.toPipeline(context);
|
||||
}
|
||||
|
||||
return aggregation.toPipeline(context).stream().map(val -> queryMapper.getMappedObject(val, Optional.empty()))
|
||||
.collect(Collectors.toList());
|
||||
}
|
||||
|
||||
/**
|
||||
* Tries to convert the given {@link RuntimeException} into a {@link DataAccessException} but returns the original
|
||||
* exception if the conversation failed. Thus allows safe re-throwing of the return value.
|
||||
|
||||
@@ -41,7 +41,7 @@ class AggregationOperationRenderer {
|
||||
* {@link Document} representation.
|
||||
*
|
||||
* @param operations must not be {@literal null}.
|
||||
* @param context must not be {@literal null}.
|
||||
* @param rootContext must not be {@literal null}.
|
||||
* @return the {@link List} of {@link Document}.
|
||||
*/
|
||||
static List<Document> toDocument(List<AggregationOperation> operations, AggregationOperationContext rootContext) {
|
||||
|
||||
@@ -664,10 +664,10 @@ public class ReactiveMongoTemplateTests {
|
||||
@Test // DATAMONGO-1444
|
||||
public void geoNear() {
|
||||
|
||||
List<Venue> venues = Arrays.asList(new Venue("Penn Station", -73.99408, 40.75057), //
|
||||
new Venue("10gen Office", -73.99171, 40.738868), //
|
||||
new Venue("Flatiron Building", -73.988135, 40.741404), //
|
||||
new Venue("Maplewood, NJ", -74.2713, 40.73137));
|
||||
List<Venue> venues = Arrays.asList(TestEntities.geolocation().pennStation(), //
|
||||
TestEntities.geolocation().tenGenOffice(), //
|
||||
TestEntities.geolocation().flatironBuilding(), //
|
||||
TestEntities.geolocation().maplewoodNJ());
|
||||
|
||||
StepVerifier.create(template.insertAll(venues)).expectNextCount(4).verifyComplete();
|
||||
|
||||
|
||||
@@ -0,0 +1,105 @@
|
||||
/*
|
||||
* Copyright 2018 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;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* A simple collection of grouped test entities used throughout the test suite.
|
||||
*
|
||||
* @author Christoph Strobl
|
||||
*/
|
||||
public class TestEntities {
|
||||
|
||||
private static final GeoEntities GEO = new GeoEntities();
|
||||
|
||||
public static GeoEntities geolocation() {
|
||||
return GEO;
|
||||
}
|
||||
|
||||
public static class GeoEntities {
|
||||
|
||||
/**
|
||||
* <pre>
|
||||
* X: -73.99408
|
||||
* Y: 40.75057
|
||||
* </pre>
|
||||
*
|
||||
* @return new {@link Venue}
|
||||
*/
|
||||
public Venue pennStation() {
|
||||
return new Venue("Penn Station", -73.99408, 40.75057);
|
||||
}
|
||||
|
||||
/**
|
||||
* <pre>
|
||||
* X: -73.99171
|
||||
* Y: 40.738868
|
||||
* </pre>
|
||||
*
|
||||
* @return new {@link Venue}
|
||||
*/
|
||||
|
||||
public Venue tenGenOffice() {
|
||||
return new Venue("10gen Office", -73.99171, 40.738868);
|
||||
}
|
||||
|
||||
/**
|
||||
* <pre>
|
||||
* X: -73.988135
|
||||
* Y: 40.741404
|
||||
* </pre>
|
||||
*
|
||||
* @return new {@link Venue}
|
||||
*/
|
||||
public Venue flatironBuilding() {
|
||||
return new Venue("Flatiron Building", -73.988135, 40.741404);
|
||||
}
|
||||
|
||||
/**
|
||||
* <pre>
|
||||
* X: -74.2713
|
||||
* Y: 40.73137
|
||||
* </pre>
|
||||
*
|
||||
* @return new {@link Venue}
|
||||
*/
|
||||
public Venue maplewoodNJ() {
|
||||
return new Venue("Maplewood, NJ", -74.2713, 40.73137);
|
||||
}
|
||||
|
||||
public List<Venue> newYork() {
|
||||
|
||||
List<Venue> venues = new ArrayList<>();
|
||||
|
||||
venues.add(pennStation());
|
||||
venues.add(tenGenOffice());
|
||||
venues.add(flatironBuilding());
|
||||
venues.add(new Venue("Players Club", -73.997812, 40.739128));
|
||||
venues.add(new Venue("City Bakery ", -73.992491, 40.738673));
|
||||
venues.add(new Venue("Splash Bar", -73.992491, 40.738673));
|
||||
venues.add(new Venue("Momofuku Milk Bar", -73.985839, 40.731698));
|
||||
venues.add(new Venue("Shake Shack", -73.98820, 40.74164));
|
||||
venues.add(new Venue("Penn Station", -73.99408, 40.75057));
|
||||
venues.add(new Venue("Empire State Building", -73.98602, 40.74894));
|
||||
venues.add(new Venue("Ulaanbaatar, Mongolia", 106.9154, 47.9245));
|
||||
venues.add(maplewoodNJ());
|
||||
|
||||
return venues;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -52,10 +52,13 @@ import org.springframework.core.io.ClassPathResource;
|
||||
import org.springframework.dao.DataAccessException;
|
||||
import org.springframework.data.annotation.Id;
|
||||
import org.springframework.data.domain.Sort.Direction;
|
||||
import org.springframework.data.geo.Box;
|
||||
import org.springframework.data.geo.Metrics;
|
||||
import org.springframework.data.geo.Point;
|
||||
import org.springframework.data.mapping.MappingException;
|
||||
import org.springframework.data.mongodb.core.CollectionCallback;
|
||||
import org.springframework.data.mongodb.core.MongoTemplate;
|
||||
import org.springframework.data.mongodb.core.TestEntities;
|
||||
import org.springframework.data.mongodb.core.Venue;
|
||||
import org.springframework.data.mongodb.core.aggregation.AggregationTests.CarDescriptor.Entry;
|
||||
import org.springframework.data.mongodb.core.aggregation.BucketAutoOperation.Granularities;
|
||||
@@ -132,6 +135,7 @@ public class AggregationTests {
|
||||
mongoTemplate.dropCollection(Employee.class);
|
||||
mongoTemplate.dropCollection(Art.class);
|
||||
mongoTemplate.dropCollection("personQueryTemp");
|
||||
mongoTemplate.dropCollection(Venue.class);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -513,7 +517,7 @@ public class AggregationTests {
|
||||
/*
|
||||
//complex mongodb aggregation framework example from
|
||||
https://docs.mongodb.org/manual/tutorial/aggregation-examples/#largest-and-smallest-cities-by-state
|
||||
|
||||
|
||||
db.zipcodes.aggregate(
|
||||
{
|
||||
$group: {
|
||||
@@ -1461,9 +1465,8 @@ public class AggregationTests {
|
||||
@Test // DATAMONGO-1127
|
||||
public void shouldSupportGeoNearQueriesForAggregationWithDistanceField() {
|
||||
|
||||
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.insertAll(Arrays.asList(TestEntities.geolocation().pennStation(),
|
||||
TestEntities.geolocation().tenGenOffice(), TestEntities.geolocation().flatironBuilding()));
|
||||
|
||||
mongoTemplate.indexOps(Venue.class).ensureIndex(new GeospatialIndex("location"));
|
||||
|
||||
@@ -1863,6 +1866,36 @@ public class AggregationTests {
|
||||
assertThat(categorizeByYear, hasSize(3));
|
||||
}
|
||||
|
||||
@Test // DATAMONGO-1986
|
||||
public void runMatchOperationCriteriaThroughQueryMapperForTypedAggregation() {
|
||||
|
||||
mongoTemplate.insertAll(TestEntities.geolocation().newYork());
|
||||
|
||||
Aggregation aggregation = newAggregation(Venue.class,
|
||||
match(Criteria.where("location")
|
||||
.within(new Box(new Point(-73.99756, 40.73083), new Point(-73.988135, 40.741404)))),
|
||||
project("id", "location", "name"));
|
||||
|
||||
AggregationResults<Document> groupResults = mongoTemplate.aggregate(aggregation, "newyork", Document.class);
|
||||
|
||||
assertThat(groupResults.getMappedResults().size(), is(4));
|
||||
}
|
||||
|
||||
@Test // DATAMONGO-1986
|
||||
public void runMatchOperationCriteriaThroughQueryMapperForUntypedAggregation() {
|
||||
|
||||
mongoTemplate.insertAll(TestEntities.geolocation().newYork());
|
||||
|
||||
Aggregation aggregation = newAggregation(
|
||||
match(Criteria.where("location")
|
||||
.within(new Box(new Point(-73.99756, 40.73083), new Point(-73.988135, 40.741404)))),
|
||||
project("id", "location", "name"));
|
||||
|
||||
AggregationResults<Document> groupResults = mongoTemplate.aggregate(aggregation, "newyork", Document.class);
|
||||
|
||||
assertThat(groupResults.getMappedResults().size(), is(4));
|
||||
}
|
||||
|
||||
private void createUsersWithReferencedPersons() {
|
||||
|
||||
mongoTemplate.dropCollection(User.class);
|
||||
|
||||
@@ -29,7 +29,12 @@ import org.junit.Before;
|
||||
import org.junit.Test;
|
||||
import org.junit.runner.RunWith;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.data.geo.Box;
|
||||
import org.springframework.data.geo.Point;
|
||||
import org.springframework.data.mongodb.core.ReactiveMongoTemplate;
|
||||
import org.springframework.data.mongodb.core.TestEntities;
|
||||
import org.springframework.data.mongodb.core.Venue;
|
||||
import org.springframework.data.mongodb.core.query.Criteria;
|
||||
import org.springframework.data.mongodb.core.query.Query;
|
||||
import org.springframework.test.context.ContextConfiguration;
|
||||
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
|
||||
@@ -65,7 +70,8 @@ public class ReactiveAggregationTests {
|
||||
.create(reactiveMongoTemplate.dropCollection(INPUT_COLLECTION) //
|
||||
.then(reactiveMongoTemplate.dropCollection(OUTPUT_COLLECTION)) //
|
||||
.then(reactiveMongoTemplate.dropCollection(Product.class)) //
|
||||
.then(reactiveMongoTemplate.dropCollection(City.class))) //
|
||||
.then(reactiveMongoTemplate.dropCollection(City.class)) //
|
||||
.then(reactiveMongoTemplate.dropCollection(Venue.class))) //
|
||||
.verifyComplete();
|
||||
}
|
||||
|
||||
@@ -128,4 +134,34 @@ public class ReactiveAggregationTests {
|
||||
StepVerifier.create(reactiveMongoTemplate.find(new Query(), City.class, OUTPUT_COLLECTION)).expectNextCount(4)
|
||||
.verifyComplete();
|
||||
}
|
||||
|
||||
@Test // DATAMONGO-1986
|
||||
public void runMatchOperationCriteriaThroughQueryMapperForTypedAggregation() {
|
||||
|
||||
reactiveMongoTemplate.insertAll(TestEntities.geolocation().newYork()).as(StepVerifier::create).expectNextCount(12)
|
||||
.verifyComplete();
|
||||
|
||||
Aggregation aggregation = newAggregation(Venue.class,
|
||||
match(Criteria.where("location")
|
||||
.within(new Box(new Point(-73.99756, 40.73083), new Point(-73.988135, 40.741404)))),
|
||||
project("id", "location", "name"));
|
||||
|
||||
reactiveMongoTemplate.aggregate(aggregation, "newyork", Document.class).as(StepVerifier::create).expectNextCount(4)
|
||||
.verifyComplete();
|
||||
}
|
||||
|
||||
@Test // DATAMONGO-1986
|
||||
public void runMatchOperationCriteriaThroughQueryMapperForUntypedAggregation() {
|
||||
|
||||
reactiveMongoTemplate.insertAll(TestEntities.geolocation().newYork()).as(StepVerifier::create).expectNextCount(12)
|
||||
.verifyComplete();
|
||||
|
||||
Aggregation aggregation = newAggregation(
|
||||
match(Criteria.where("location")
|
||||
.within(new Box(new Point(-73.99756, 40.73083), new Point(-73.988135, 40.741404)))),
|
||||
project("id", "location", "name"));
|
||||
|
||||
reactiveMongoTemplate.aggregate(aggregation, "newyork", Document.class).as(StepVerifier::create).expectNextCount(4)
|
||||
.verifyComplete();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -62,7 +62,6 @@ public class ReactiveAggregationUnitTests {
|
||||
when(db.getCollection(eq(INPUT_COLLECTION), any(Class.class))).thenReturn(collection);
|
||||
when(collection.aggregate(anyList(), any(Class.class))).thenReturn(publisher);
|
||||
when(publisher.allowDiskUse(any())).thenReturn(publisher);
|
||||
when(publisher.useCursor(any())).thenReturn(publisher);
|
||||
when(publisher.collation(any())).thenReturn(publisher);
|
||||
}
|
||||
|
||||
|
||||
@@ -38,13 +38,13 @@ import org.springframework.data.geo.Point;
|
||||
import org.springframework.data.geo.Polygon;
|
||||
import org.springframework.data.mongodb.config.AbstractMongoConfiguration;
|
||||
import org.springframework.data.mongodb.core.MongoTemplate;
|
||||
import org.springframework.data.mongodb.core.TestEntities;
|
||||
import org.springframework.data.mongodb.core.Venue;
|
||||
import org.springframework.data.mongodb.core.query.NearQuery;
|
||||
import org.springframework.data.mongodb.core.query.Query;
|
||||
import org.springframework.test.context.ContextConfiguration;
|
||||
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
|
||||
|
||||
import com.mongodb.Mongo;
|
||||
import com.mongodb.MongoClient;
|
||||
import com.mongodb.WriteConcern;
|
||||
|
||||
@@ -103,19 +103,7 @@ public abstract class AbstractGeoSpatialTests {
|
||||
}
|
||||
|
||||
protected void addVenues() {
|
||||
|
||||
template.insert(new Venue("Penn Station", -73.99408, 40.75057));
|
||||
template.insert(new Venue("10gen Office", -73.99171, 40.738868));
|
||||
template.insert(new Venue("Flatiron Building", -73.988135, 40.741404));
|
||||
template.insert(new Venue("Players Club", -73.997812, 40.739128));
|
||||
template.insert(new Venue("City Bakery ", -73.992491, 40.738673));
|
||||
template.insert(new Venue("Splash Bar", -73.992491, 40.738673));
|
||||
template.insert(new Venue("Momofuku Milk Bar", -73.985839, 40.731698));
|
||||
template.insert(new Venue("Shake Shack", -73.98820, 40.74164));
|
||||
template.insert(new Venue("Penn Station", -73.99408, 40.75057));
|
||||
template.insert(new Venue("Empire State Building", -73.98602, 40.74894));
|
||||
template.insert(new Venue("Ulaanbaatar, Mongolia", 106.9154, 47.9245));
|
||||
template.insert(new Venue("Maplewood, NJ", -74.2713, 40.73137));
|
||||
template.insertAll(TestEntities.geolocation().newYork());
|
||||
}
|
||||
|
||||
@Test
|
||||
|
||||
Reference in New Issue
Block a user