diff --git a/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/MongoTemplate.java b/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/MongoTemplate.java index 79e1d603a..9fd71d2b4 100644 --- a/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/MongoTemplate.java +++ b/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/MongoTemplate.java @@ -53,6 +53,7 @@ import org.springframework.data.geo.Distance; import org.springframework.data.geo.GeoResult; import org.springframework.data.geo.GeoResults; import org.springframework.data.geo.Metric; +import org.springframework.data.geo.Point; import org.springframework.data.mapping.PropertyPath; import org.springframework.data.mapping.PropertyReferenceException; import org.springframework.data.mapping.callback.EntityCallbacks; @@ -1191,11 +1192,7 @@ public class MongoTemplate implements MongoOperations, ApplicationContextAware, LOGGER.debug("Executing count: {} in collection: {}", serializeToJsonSafely(filter), collectionName); } - if (MongoDatabaseUtils.isTransactionActive(getMongoDbFactory())) { - return execute(collectionName, collection -> collection.countDocuments(filter, options)); - } - - return execute(collectionName, collection -> collection.count(filter, options)); + return execute(collectionName, collection -> collection.countDocuments(QueryMapper.processCountFilter(filter), options)); } /* @@ -3523,19 +3520,5 @@ public class MongoTemplate implements MongoOperations, ApplicationContextAware, // native MongoDB objects that offer methods with ClientSession must not be proxied. return delegate.getDb(); } - - /* - * (non-Javadoc) - * @see org.springframework.data.mongodb.core.MongoTemplate#doCount(java.lang.String, org.bson.Document, com.mongodb.client.model.CountOptions) - */ - @Override - protected long doCount(String collectionName, Document filter, CountOptions options) { - - if (!session.hasActiveTransaction()) { - return super.doCount(collectionName, filter, options); - } - - return execute(collectionName, collection -> collection.countDocuments(filter, options)); - } } } diff --git a/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/ReactiveMongoTemplate.java b/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/ReactiveMongoTemplate.java index 0dcab3e87..8c53d8eeb 100644 --- a/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/ReactiveMongoTemplate.java +++ b/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/ReactiveMongoTemplate.java @@ -1300,9 +1300,8 @@ public class ReactiveMongoTemplate implements ReactiveMongoOperations, Applicati */ protected Mono doCount(String collectionName, Document filter, CountOptions options) { - return ReactiveMongoDatabaseUtils.isTransactionActive(mongoDatabaseFactory) // - .flatMap(txActive -> createMono(collectionName, - collection -> txActive ? collection.countDocuments(filter, options) : collection.count(filter, options))); + return createMono(collectionName, + collection -> collection.countDocuments(QueryMapper.processCountFilter(filter), options)); } /* @@ -3323,20 +3322,6 @@ public class ReactiveMongoTemplate implements ReactiveMongoOperations, Applicati // native MongoDB objects that offer methods with ClientSession must not be proxied. return delegate.getMongoDatabase(); } - - /* - * (non-Javadoc) - * @see org.springframework.data.mongodb.core.ReactiveMongoTemplate#count(java.lang.String, org.bson.Document, com.mongodb.client.model.CountOptions) - */ - @Override - public Mono doCount(String collectionName, Document filter, CountOptions options) { - - if (!session.hasActiveTransaction()) { - return super.doCount(collectionName, filter, options); - } - - return createMono(collectionName, collection -> collection.countDocuments(filter, options)); - } } @RequiredArgsConstructor diff --git a/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/convert/QueryMapper.java b/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/convert/QueryMapper.java index b1f984a3e..674c49fb3 100644 --- a/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/convert/QueryMapper.java +++ b/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/convert/QueryMapper.java @@ -15,17 +15,8 @@ */ package org.springframework.data.mongodb.core.convert; -import java.util.ArrayList; -import java.util.Arrays; -import java.util.Collections; -import java.util.HashSet; -import java.util.Iterator; -import java.util.LinkedHashMap; -import java.util.List; -import java.util.Map; +import java.util.*; import java.util.Map.Entry; -import java.util.Optional; -import java.util.Set; import java.util.regex.Matcher; import java.util.regex.Pattern; @@ -36,6 +27,7 @@ import org.bson.types.ObjectId; import org.springframework.core.convert.ConversionService; import org.springframework.core.convert.converter.Converter; import org.springframework.data.domain.Example; +import org.springframework.data.geo.Point; import org.springframework.data.mapping.Association; import org.springframework.data.mapping.MappingException; import org.springframework.data.mapping.PersistentEntity; @@ -1290,4 +1282,97 @@ public class QueryMapper { public MappingContext, MongoPersistentProperty> getMappingContext() { return mappingContext; } + + public static Document processCountFilter(Document source) { + + Document target = new Document(); + for (Entry entry : source.entrySet()) { + + if (entry.getValue() instanceof Document) { + + Document theValue = (Document) entry.getValue(); + if (containsNear(theValue)) { + target.putAll(createGeoWithin(entry.getKey(), theValue)); + } else { + target.put(entry.getKey(), entry.getValue()); + } + } else if (entry.getValue() instanceof Collection) { + + Collection tmp = new ArrayList<>(); + for (Object val : (Collection) entry.getValue()) { + if (val instanceof Document) { + tmp.add(processCountFilter((Document) val)); + } else { + tmp.add(val); + } + } + target.put(entry.getKey(), tmp); + } else { + target.put(entry.getKey(), entry.getValue()); + } + } + return target; + } + + private static Document createGeoWithin(String key, Document source) { + + boolean spheric = source.containsKey("$nearSphere"); + Object $near = spheric ? source.get("$nearSphere") : source.get("$near"); + + Number maxDistance = source.containsKey("$maxDistance") ? (Number) source.get("$maxDistance") : Double.MAX_VALUE; + List $centerMax = Arrays.asList(toCenterCoordinates($near), maxDistance); + Document $geoWithinMax = new Document("$geoWithin", + new Document(spheric ? "$centerSphere" : "$center", $centerMax)); + + if (!containsNearWithMinDistance(source)) { + return new Document(key, $geoWithinMax); + } + + Number minDistance = (Number) source.get("$minDistance"); + List $centerMin = Arrays.asList(toCenterCoordinates($near), minDistance); + Document $geoWithinMin = new Document("$geoWithin", + new Document(spheric ? "$centerSphere" : "$center", $centerMin)); + + List criteria = new ArrayList<>(); + criteria.add(new Document("$nor", Arrays.asList(new Document(key, $geoWithinMin)))); + criteria.add(new Document(key, $geoWithinMax)); + return new Document("$and", criteria); + } + + private static boolean containsNear(Document source) { + + if (source.containsKey("$near") || source.containsKey("$nearSphere")) { + return true; + } + + return false; + } + + private static boolean containsNearWithMinDistance(Document source) { + + if (!containsNear(source)) { + return false; + } + + return source.containsKey("$minDistance"); + } + + private static Object toCenterCoordinates(Object value) { + + if (ObjectUtils.isArray(value)) { + return value; + } + + if (value instanceof Point) { + return Arrays.asList(((Point) value).getX(), ((Point) value).getY()); + } + + if (value instanceof Document && ((Document) value).containsKey("x")) { + + Document point = (Document) value; + return Arrays.asList(point.get("x"), point.get("y")); + } + + return value; + } } diff --git a/spring-data-mongodb/src/test/java/org/springframework/data/mongodb/SessionAwareMethodInterceptorUnitTests.java b/spring-data-mongodb/src/test/java/org/springframework/data/mongodb/SessionAwareMethodInterceptorUnitTests.java index cd221cb03..29a7a432c 100644 --- a/spring-data-mongodb/src/test/java/org/springframework/data/mongodb/SessionAwareMethodInterceptorUnitTests.java +++ b/spring-data-mongodb/src/test/java/org/springframework/data/mongodb/SessionAwareMethodInterceptorUnitTests.java @@ -107,11 +107,11 @@ public class SessionAwareMethodInterceptorUnitTests { public void usesCacheForMethodLookup() { MethodCache cache = (MethodCache) ReflectionTestUtils.getField(SessionAwareMethodInterceptor.class, "METHOD_CACHE"); - Method countMethod = ClassUtils.getMethod(MongoCollection.class, "count"); + Method countMethod = ClassUtils.getMethod(MongoCollection.class, "countDocuments"); assertThat(cache.contains(countMethod, MongoCollection.class)).isFalse(); - collection.count(); + collection.countDocuments(); assertThat(cache.contains(countMethod, MongoCollection.class)).isTrue(); } diff --git a/spring-data-mongodb/src/test/java/org/springframework/data/mongodb/core/MongoTemplateUnitTests.java b/spring-data-mongodb/src/test/java/org/springframework/data/mongodb/core/MongoTemplateUnitTests.java index eed5cbd9d..6b8813734 100644 --- a/spring-data-mongodb/src/test/java/org/springframework/data/mongodb/core/MongoTemplateUnitTests.java +++ b/spring-data-mongodb/src/test/java/org/springframework/data/mongodb/core/MongoTemplateUnitTests.java @@ -154,7 +154,7 @@ public class MongoTemplateUnitTests extends MongoOperationsUnitTests { when(db.runCommand(any(), any(Class.class))).thenReturn(commandResultDocument); when(collection.find(any(org.bson.Document.class), any(Class.class))).thenReturn(findIterable); when(collection.mapReduce(any(), any(), eq(Document.class))).thenReturn(mapReduceIterable); - when(collection.count(any(Bson.class), any(CountOptions.class))).thenReturn(1L); // TODO: MongoDB 4 - fix me + when(collection.countDocuments(any(Bson.class), any(CountOptions.class))).thenReturn(1L); // TODO: MongoDB 4 - fix me when(collection.getNamespace()).thenReturn(new MongoNamespace("db.mock-collection")); when(collection.aggregate(any(List.class), any())).thenReturn(aggregateIterable); when(collection.withReadPreference(any())).thenReturn(collection); @@ -735,7 +735,7 @@ public class MongoTemplateUnitTests extends MongoOperationsUnitTests { template.exists(new BasicQuery("{}").collation(Collation.of("fr")), AutogenerateableId.class); ArgumentCaptor options = ArgumentCaptor.forClass(CountOptions.class); - verify(collection).count(any(), options.capture()); + verify(collection).countDocuments(any(), options.capture()); assertThat(options.getValue().getCollation()) .isEqualTo(com.mongodb.client.model.Collation.builder().locale("fr").build()); @@ -926,7 +926,7 @@ public class MongoTemplateUnitTests extends MongoOperationsUnitTests { template.count(new BasicQuery("{}").collation(Collation.of("fr")), AutogenerateableId.class); ArgumentCaptor options = ArgumentCaptor.forClass(CountOptions.class); - verify(collection).count(any(), options.capture()); + verify(collection).countDocuments(any(), options.capture()); assertThat(options.getValue().getCollation()) .isEqualTo(com.mongodb.client.model.Collation.builder().locale("fr").build()); @@ -939,7 +939,7 @@ public class MongoTemplateUnitTests extends MongoOperationsUnitTests { template.count(new BasicQuery("{}").withHint(queryHint), AutogenerateableId.class); ArgumentCaptor options = ArgumentCaptor.forClass(CountOptions.class); - verify(collection).count(any(), options.capture()); + verify(collection).countDocuments(any(), options.capture()); assertThat(options.getValue().getHint()).isEqualTo(queryHint); } @@ -1068,7 +1068,7 @@ public class MongoTemplateUnitTests extends MongoOperationsUnitTests { template.count(new BasicQuery("{}").skip(100), AutogenerateableId.class); ArgumentCaptor options = ArgumentCaptor.forClass(CountOptions.class); - verify(collection).count(any(), options.capture()); + verify(collection).countDocuments(any(), options.capture()); assertThat(options.getValue().getSkip()).isEqualTo(100); } @@ -1079,7 +1079,7 @@ public class MongoTemplateUnitTests extends MongoOperationsUnitTests { template.count(new BasicQuery("{}").limit(10), AutogenerateableId.class); ArgumentCaptor options = ArgumentCaptor.forClass(CountOptions.class); - verify(collection).count(any(), options.capture()); + verify(collection).countDocuments(any(), options.capture()); assertThat(options.getValue().getLimit()).isEqualTo(10); } @@ -1150,7 +1150,7 @@ public class MongoTemplateUnitTests extends MongoOperationsUnitTests { template.exists(new BasicQuery("{}"), Sith.class); ArgumentCaptor options = ArgumentCaptor.forClass(CountOptions.class); - verify(collection).count(any(), options.capture()); + verify(collection).countDocuments(any(), options.capture()); assertThat(options.getValue().getCollation()) .isEqualTo(com.mongodb.client.model.Collation.builder().locale("de_AT").build()); diff --git a/spring-data-mongodb/src/test/java/org/springframework/data/mongodb/core/ReactiveMongoTemplateUnitTests.java b/spring-data-mongodb/src/test/java/org/springframework/data/mongodb/core/ReactiveMongoTemplateUnitTests.java index 2daed014b..6e5becebd 100644 --- a/spring-data-mongodb/src/test/java/org/springframework/data/mongodb/core/ReactiveMongoTemplateUnitTests.java +++ b/spring-data-mongodb/src/test/java/org/springframework/data/mongodb/core/ReactiveMongoTemplateUnitTests.java @@ -126,7 +126,7 @@ public class ReactiveMongoTemplateUnitTests { when(collection.find(any(Document.class), any(Class.class))).thenReturn(findPublisher); when(collection.aggregate(anyList())).thenReturn(aggregatePublisher); when(collection.aggregate(anyList(), any(Class.class))).thenReturn(aggregatePublisher); - when(collection.count(any(), any(CountOptions.class))).thenReturn(Mono.just(0L)); + when(collection.countDocuments(any(), any(CountOptions.class))).thenReturn(Mono.just(0L)); when(collection.updateOne(any(), any(Bson.class), any(UpdateOptions.class))).thenReturn(updateResultPublisher); when(collection.updateMany(any(Bson.class), any(Bson.class), any())).thenReturn(updateResultPublisher); when(collection.findOneAndUpdate(any(), any(Bson.class), any(FindOneAndUpdateOptions.class))) @@ -391,7 +391,7 @@ public class ReactiveMongoTemplateUnitTests { template.count(new Query().skip(10), Person.class, "star-wars").subscribe(); ArgumentCaptor options = ArgumentCaptor.forClass(CountOptions.class); - verify(collection).count(any(), options.capture()); + verify(collection).countDocuments(any(), options.capture()); assertThat(options.getValue().getSkip()).isEqualTo(10); } @@ -402,7 +402,7 @@ public class ReactiveMongoTemplateUnitTests { template.count(new Query().limit(100), Person.class, "star-wars").subscribe(); ArgumentCaptor options = ArgumentCaptor.forClass(CountOptions.class); - verify(collection).count(any(), options.capture()); + verify(collection).countDocuments(any(), options.capture()); assertThat(options.getValue().getLimit()).isEqualTo(100); } @@ -414,7 +414,7 @@ public class ReactiveMongoTemplateUnitTests { template.count(new Query().withHint(queryHint), Person.class, "star-wars").subscribe(); ArgumentCaptor options = ArgumentCaptor.forClass(CountOptions.class); - verify(collection).count(any(), options.capture()); + verify(collection).countDocuments(any(), options.capture()); assertThat(options.getValue().getHint()).isEqualTo(queryHint); } diff --git a/spring-data-mongodb/src/test/java/org/springframework/data/mongodb/core/ReactiveSessionBoundMongoTemplateUnitTests.java b/spring-data-mongodb/src/test/java/org/springframework/data/mongodb/core/ReactiveSessionBoundMongoTemplateUnitTests.java index bee7bee0f..a35d32c10 100644 --- a/spring-data-mongodb/src/test/java/org/springframework/data/mongodb/core/ReactiveSessionBoundMongoTemplateUnitTests.java +++ b/spring-data-mongodb/src/test/java/org/springframework/data/mongodb/core/ReactiveSessionBoundMongoTemplateUnitTests.java @@ -111,7 +111,7 @@ public class ReactiveSessionBoundMongoTemplateUnitTests { when(collection.deleteMany(any(ClientSession.class), any(), any())).thenReturn(resultPublisher); when(collection.insertOne(any(ClientSession.class), any(Document.class))).thenReturn(resultPublisher); when(collection.aggregate(any(ClientSession.class), anyList(), any(Class.class))).thenReturn(aggregatePublisher); - when(collection.count(any(ClientSession.class), any(), any(CountOptions.class))).thenReturn(resultPublisher); + when(collection.countDocuments(any(ClientSession.class), any(), any(CountOptions.class))).thenReturn(resultPublisher); when(collection.drop(any(ClientSession.class))).thenReturn(resultPublisher); when(collection.findOneAndUpdate(any(ClientSession.class), any(), any(Bson.class), any())) .thenReturn(resultPublisher); @@ -224,7 +224,7 @@ public class ReactiveSessionBoundMongoTemplateUnitTests { template.count(new Query(), Person.class).subscribe(); - verify(collection).count(eq(clientSession), any(), any(CountOptions.class)); + verify(collection).countDocuments(eq(clientSession), any(), any(CountOptions.class)); } @Test // DATAMONGO-1880 diff --git a/spring-data-mongodb/src/test/java/org/springframework/data/mongodb/core/SessionBoundMongoTemplateTests.java b/spring-data-mongodb/src/test/java/org/springframework/data/mongodb/core/SessionBoundMongoTemplateTests.java index 1fe289f6f..fd0adfe6c 100644 --- a/spring-data-mongodb/src/test/java/org/springframework/data/mongodb/core/SessionBoundMongoTemplateTests.java +++ b/spring-data-mongodb/src/test/java/org/springframework/data/mongodb/core/SessionBoundMongoTemplateTests.java @@ -284,7 +284,6 @@ public class SessionBoundMongoTemplateTests { } @Test // DATAMONGO-2012 - @Ignore("error 2 (BadValue): $match does not support $geoNear, $near, and $nearSphere") public void countWithGeoInTransaction() { if (!template.collectionExists(Person.class)) { diff --git a/spring-data-mongodb/src/test/java/org/springframework/data/mongodb/core/SessionBoundMongoTemplateUnitTests.java b/spring-data-mongodb/src/test/java/org/springframework/data/mongodb/core/SessionBoundMongoTemplateUnitTests.java index 08f1660bf..fe9027ace 100644 --- a/spring-data-mongodb/src/test/java/org/springframework/data/mongodb/core/SessionBoundMongoTemplateUnitTests.java +++ b/spring-data-mongodb/src/test/java/org/springframework/data/mongodb/core/SessionBoundMongoTemplateUnitTests.java @@ -226,7 +226,7 @@ public class SessionBoundMongoTemplateUnitTests { template.count(new Query(), Person.class); - verify(collection).count(eq(clientSession), any(), any(CountOptions.class)); + verify(collection).countDocuments(eq(clientSession), any(), any(CountOptions.class)); } @Test // DATAMONGO-1880 diff --git a/spring-data-mongodb/src/test/java/org/springframework/data/mongodb/core/convert/QueryMapperUnitTests.java b/spring-data-mongodb/src/test/java/org/springframework/data/mongodb/core/convert/QueryMapperUnitTests.java index d1fd28622..9ec635474 100755 --- a/spring-data-mongodb/src/test/java/org/springframework/data/mongodb/core/convert/QueryMapperUnitTests.java +++ b/spring-data-mongodb/src/test/java/org/springframework/data/mongodb/core/convert/QueryMapperUnitTests.java @@ -890,6 +890,96 @@ public class QueryMapperUnitTests { assertThat(target).isEqualTo(new org.bson.Document("_id", "id-1")); } + @Test // DATAMONGO-2059 + public void nearToGeoWithinWithoutDistance() { + + Query source = query(where("location").near(new Point(-73.99171, 40.738868))); + org.bson.Document target = postProcessQueryForCount(source); + + assertThat(target).isEqualTo(org.bson.Document + .parse("{\"location\": {\"$geoWithin\": {\"$center\": [[-73.99171, 40.738868], 1.7976931348623157E308]}}}")); + } + + @Test // DATAMONGO-2059 + public void nearSphereToGeoWithinWithoutDistance() { + + Query source = query(where("location").nearSphere(new Point(-73.99171, 40.738868))); + org.bson.Document target = postProcessQueryForCount(source); + + assertThat(target).isEqualTo(org.bson.Document.parse( + "{\"location\": {\"$geoWithin\": {\"$centerSphere\": [[-73.99171, 40.738868], 1.7976931348623157E308]}}}")); + } + + @Test // DATAMONGO-2059 + public void nearToGeoWithinWithMaxDistance() { + + Query source = query(where("location").near(new Point(-73.99171, 40.738868)).maxDistance(10)); + org.bson.Document target = postProcessQueryForCount(source); + + assertThat(target).isEqualTo( + org.bson.Document.parse("{\"location\": {\"$geoWithin\": {\"$center\": [[-73.99171, 40.738868], 10.0]}}}")); + } + + @Test // DATAMONGO-2059 + public void nearSphereToGeoWithinWithMaxDistance() { + + Query source = query(where("location").nearSphere(new Point(-73.99171, 40.738868)).maxDistance(10)); + org.bson.Document target = postProcessQueryForCount(source); + + assertThat(target).isEqualTo(org.bson.Document + .parse("{\"location\": {\"$geoWithin\": {\"$centerSphere\": [[-73.99171, 40.738868], 10.0]}}}")); + } + + @Test // DATAMONGO-2059 + public void nearToGeoWithinWithMinDistance() { + + Query source = query(where("location").near(new Point(-73.99171, 40.738868)).minDistance(0.01)); + org.bson.Document target = postProcessQueryForCount(source); + + assertThat(target).isEqualTo(org.bson.Document.parse( + "{\"$and\":[{\"$nor\":[{\"location\":{\"$geoWithin\":{\"$center\":[ [ -73.99171, 40.738868 ], 0.01]}}}]}," + + " {\"location\":{\"$geoWithin\":{\"$center\":[ [ -73.99171, 40.738868 ], 1.7976931348623157E308]}}}]}")); + } + + @Test // DATAMONGO-2059 + public void nearToGeoWithinWithMaxDistanceAndCombinedWithOtherCriteria() { + + Query source = query( + where("name").is("food").and("location").near(new Point(-73.99171, 40.738868)).maxDistance(10)); + org.bson.Document target = postProcessQueryForCount(source); + + assertThat(target).isEqualTo(org.bson.Document + .parse("{\"name\": \"food\", \"location\": {\"$geoWithin\": {\"$center\": [[-73.99171, 40.738868], 10.0]}}}")); + } + + @Test // DATAMONGO-2059 + public void nearToGeoWithinWithMinDistanceOrCombinedWithOtherCriteria() { + + Query source = query(new Criteria().orOperator(where("name").is("food"), + where("location").near(new Point(-73.99171, 40.738868)).minDistance(0.01))); + org.bson.Document target = postProcessQueryForCount(source); + + assertThat(target).isEqualTo(org.bson.Document.parse( + "{\"$or\" : [ { \"name\": \"food\" }, {\"$and\":[{\"$nor\":[{\"location\":{\"$geoWithin\":{\"$center\":[ [ -73.99171, 40.738868 ], 0.01]}}}]},{\"location\":{\"$geoWithin\":{\"$center\":[ [ -73.99171, 40.738868 ], 1.7976931348623157E308]}}}]} ]}")); + } + + @Test // DATAMONGO-2059 + public void nearToGeoWithinWithMaxDistanceOrCombinedWithOtherCriteria() { + + Query source = query(new Criteria().orOperator(where("name").is("food"), + where("location").near(new Point(-73.99171, 40.738868)).maxDistance(10))); + org.bson.Document target = postProcessQueryForCount(source); + + assertThat(target).isEqualTo(org.bson.Document.parse( + "{\"$or\" : [ { \"name\": \"food\" }, {\"location\": {\"$geoWithin\": {\"$center\": [[-73.99171, 40.738868], 10.0]}}} ]}")); + } + + private org.bson.Document postProcessQueryForCount(Query source) { + + org.bson.Document intermediate = mapper.getMappedObject(source.getQueryObject(), (MongoPersistentEntity) null); + return QueryMapper.processCountFilter(intermediate); + } + @Document public class Foo { @Id private ObjectId id; diff --git a/spring-data-mongodb/src/test/java/org/springframework/data/mongodb/core/geo/AbstractGeoSpatialTests.java b/spring-data-mongodb/src/test/java/org/springframework/data/mongodb/core/geo/AbstractGeoSpatialTests.java index a96489eda..8355c60f3 100644 --- a/spring-data-mongodb/src/test/java/org/springframework/data/mongodb/core/geo/AbstractGeoSpatialTests.java +++ b/spring-data-mongodb/src/test/java/org/springframework/data/mongodb/core/geo/AbstractGeoSpatialTests.java @@ -120,24 +120,33 @@ public abstract class AbstractGeoSpatialTests { public void withinCenter() { Circle circle = new Circle(-73.99171, 40.738868, 0.01); - List venues = template.find(query(where("location").within(circle)), Venue.class); + Query query = query(where("location").within(circle)); + List venues = template.find(query, Venue.class); + assertThat(venues).hasSize(7); + assertThat(template.count(query, Venue.class)).isEqualTo(7); } @Test public void withinCenterSphere() { Circle circle = new Circle(-73.99171, 40.738868, 0.003712240453784); - List venues = template.find(query(where("location").withinSphere(circle)), Venue.class); + Query query = query(where("location").withinSphere(circle)); + + List venues = template.find(query, Venue.class); assertThat(venues).hasSize(11); + assertThat(template.count(query, Venue.class)).isEqualTo(11); } @Test public void withinBox() { Box box = new Box(new Point(-73.99756, 40.73083), new Point(-73.988135, 40.741404)); - List venues = template.find(query(where("location").within(box)), Venue.class); + Query query = query(where("location").within(box)); + + List venues = template.find(query, Venue.class); assertThat(venues).hasSize(4); + assertThat(template.count(query, Venue.class)).isEqualTo(4); } @Test @@ -150,8 +159,10 @@ public abstract class AbstractGeoSpatialTests { Polygon polygon = new Polygon(first, second, third, fourth); - List venues = template.find(query(where("location").within(polygon)), Venue.class); + Query query = query(where("location").within(polygon)); + List venues = template.find(query, Venue.class); assertThat(venues).hasSize(4); + assertThat(template.count(query, Venue.class)).isEqualTo(4); } @Test @@ -159,8 +170,10 @@ public abstract class AbstractGeoSpatialTests { Point point = new Point(-73.99171, 40.738868); Query query = query(where("location").nearSphere(point).maxDistance(0.003712240453784)); + List venues = template.find(query, Venue.class); assertThat(venues).hasSize(11); + assertThat(template.count(query, Venue.class)).isEqualTo(11); } @Test // DATAMONGO-1360 diff --git a/spring-data-mongodb/src/test/java/org/springframework/data/mongodb/core/geo/GeoSpatial2DSphereTests.java b/spring-data-mongodb/src/test/java/org/springframework/data/mongodb/core/geo/GeoSpatial2DSphereTests.java index f58ef2ceb..1240bcdaf 100644 --- a/spring-data-mongodb/src/test/java/org/springframework/data/mongodb/core/geo/GeoSpatial2DSphereTests.java +++ b/spring-data-mongodb/src/test/java/org/springframework/data/mongodb/core/geo/GeoSpatial2DSphereTests.java @@ -22,6 +22,7 @@ import static org.springframework.data.mongodb.core.query.Query.*; import java.util.List; +import org.junit.Ignore; import org.junit.Test; import org.springframework.data.domain.Sort.Direction; @@ -36,6 +37,7 @@ import org.springframework.data.mongodb.core.index.IndexField; import org.springframework.data.mongodb.core.index.IndexInfo; import org.springframework.data.mongodb.core.index.IndexOperations; import org.springframework.data.mongodb.core.query.NearQuery; +import org.springframework.data.mongodb.core.query.Query; /** * @author Christoph Strobl @@ -72,11 +74,23 @@ public class GeoSpatial2DSphereTests extends AbstractGeoSpatialTests { @Test // DATAMONGO-1110 public void nearSphereWithMinDistance() { + Point point = new Point(-73.99171, 40.738868); - List venues = template.find(query(where("location").nearSphere(point).minDistance(0.01)), Venue.class); + Query query = query(where("location").nearSphere(point).minDistance(0.01)); + + List venues = template.find(query, Venue.class); assertThat(venues.size()).isEqualTo(1); } + @Test + public void countNearSphereWithMinDistance() { + + Point point = new Point(-73.99171, 40.738868); + Query query = query(where("location").nearSphere(point).minDistance(0.01)); + + assertThat(template.count(query, Venue.class)).isEqualTo(1); + } + @Override protected void createIndex() { template.indexOps(Venue.class).ensureIndex(new GeospatialIndex("location").typed(GeoSpatialIndexType.GEO_2DSPHERE)); diff --git a/spring-data-mongodb/src/test/java/org/springframework/data/mongodb/core/geo/GeoSpatial2DTests.java b/spring-data-mongodb/src/test/java/org/springframework/data/mongodb/core/geo/GeoSpatial2DTests.java index 74ce4af6c..1adb751f5 100644 --- a/spring-data-mongodb/src/test/java/org/springframework/data/mongodb/core/geo/GeoSpatial2DTests.java +++ b/spring-data-mongodb/src/test/java/org/springframework/data/mongodb/core/geo/GeoSpatial2DTests.java @@ -32,6 +32,7 @@ import org.springframework.data.mongodb.core.index.GeospatialIndex; import org.springframework.data.mongodb.core.index.IndexField; import org.springframework.data.mongodb.core.index.IndexInfo; import org.springframework.data.mongodb.core.index.IndexOperations; +import org.springframework.data.mongodb.core.query.Query; /** * Modified from https://github.com/deftlabs/mongo-java-geospatial-example @@ -45,9 +46,13 @@ public class GeoSpatial2DTests extends AbstractGeoSpatialTests { @Test public void nearPoint() { + Point point = new Point(-73.99171, 40.738868); - List venues = template.find(query(where("location").near(point).maxDistance(0.01)), Venue.class); + Query query = query(where("location").near(point).maxDistance(0.01)); + + List venues = template.find(query, Venue.class); assertThat(venues.size()).isEqualTo(7); + assertThat(template.count(query, Venue.class)).isEqualTo(7); } @Test // DATAMONGO-360