DATAMONGO-1134 - Add support for $geoIntersects.
We now support $geoIntersects via Criteria.intersects(…) using GeoJSON types. Original pull request: #295.
This commit is contained in:
committed by
Oliver Gierke
parent
ea84f08de8
commit
ee04c014c9
@@ -222,7 +222,7 @@ public class QueryMapper {
|
||||
protected DBObject getMappedKeyword(Keyword keyword, MongoPersistentEntity<?> entity) {
|
||||
|
||||
// $or/$nor
|
||||
if (keyword.isOrOrNor() || keyword.hasIterableValue()) {
|
||||
if (keyword.isOrOrNor() || (keyword.hasIterableValue() && !keyword.isGeometry())) {
|
||||
|
||||
Iterable<?> conditions = keyword.getValue();
|
||||
BasicDBList newConditions = new BasicDBList();
|
||||
@@ -552,6 +552,16 @@ public class QueryMapper {
|
||||
return key.matches(N_OR_PATTERN);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns whether the current keyword is the {@code $geometry} keyword.
|
||||
*
|
||||
* @return
|
||||
* @since 1.8
|
||||
*/
|
||||
public boolean isGeometry() {
|
||||
return "$geometry".equalsIgnoreCase(key);
|
||||
}
|
||||
|
||||
public boolean hasIterableValue() {
|
||||
return value instanceof Iterable;
|
||||
}
|
||||
|
||||
@@ -190,8 +190,8 @@ public class Criteria implements CriteriaDefinition {
|
||||
*/
|
||||
public Criteria in(Object... o) {
|
||||
if (o.length > 1 && o[1] instanceof Collection) {
|
||||
throw new InvalidMongoDbApiUsageException("You can only pass in one argument of type "
|
||||
+ o[1].getClass().getName());
|
||||
throw new InvalidMongoDbApiUsageException(
|
||||
"You can only pass in one argument of type " + o[1].getClass().getName());
|
||||
}
|
||||
criteria.put("$in", Arrays.asList(o));
|
||||
return this;
|
||||
@@ -433,7 +433,23 @@ public class Criteria implements CriteriaDefinition {
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a geospatical criterion using a {@literal $maxDistance} operation, for use with $near
|
||||
* Creates criterion using {@code $geoIntersects} operator which matches intersections of the given {@code geoJson}
|
||||
* structure and the documents one. Requires MongoDB 2.4 or better.
|
||||
*
|
||||
* @param geoJson must not be {@literal null}.
|
||||
* @return
|
||||
* @since 1.8
|
||||
*/
|
||||
@SuppressWarnings("rawtypes")
|
||||
public Criteria intersects(GeoJson geoJson) {
|
||||
|
||||
Assert.notNull(geoJson, "GeoJson must not be null!");
|
||||
criteria.put("$geoIntersects", geoJson);
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a geo-spatial criterion using a {@literal $maxDistance} operation, for use with $near
|
||||
*
|
||||
* @see http://docs.mongodb.org/manual/reference/operator/query/maxDistance/
|
||||
* @param maxDistance
|
||||
@@ -526,8 +542,8 @@ public class Criteria implements CriteriaDefinition {
|
||||
private Criteria registerCriteriaChainElement(Criteria criteria) {
|
||||
|
||||
if (lastOperatorWasNot()) {
|
||||
throw new IllegalArgumentException("operator $not is not allowed around criteria chain element: "
|
||||
+ criteria.getCriteriaObject());
|
||||
throw new IllegalArgumentException(
|
||||
"operator $not is not allowed around criteria chain element: " + criteria.getCriteriaObject());
|
||||
} else {
|
||||
criteriaChain.add(criteria);
|
||||
}
|
||||
|
||||
@@ -775,6 +775,21 @@ public class QueryMapperUnitTests {
|
||||
assertThat(dbo, isBsonObject().containing("geoJsonPoint.$geoWithin.$geometry.type", "Polygon"));
|
||||
}
|
||||
|
||||
/**
|
||||
* @see DATAMONGO-1134
|
||||
*/
|
||||
@Test
|
||||
public void intersectsShouldUseGeoJsonRepresentationCorrectly() {
|
||||
|
||||
Query query = query(where("geoJsonPoint").intersects(
|
||||
new GeoJsonPolygon(new Point(0, 0), new Point(100, 100), new Point(100, 0), new Point(0, 0))));
|
||||
|
||||
DBObject dbo = mapper.getMappedObject(query.getQueryObject(), context.getPersistentEntity(ClassWithGeoTypes.class));
|
||||
|
||||
assertThat(dbo, isBsonObject().containing("geoJsonPoint.$geoIntersects.$geometry.type", "Polygon"));
|
||||
assertThat(dbo, isBsonObject().containing("geoJsonPoint.$geoIntersects.$geometry.coordinates"));
|
||||
}
|
||||
|
||||
@Document
|
||||
public class Foo {
|
||||
@Id private ObjectId id;
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2010-2014 the original author or authors.
|
||||
* Copyright 2010-2015 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.
|
||||
@@ -17,12 +17,13 @@ package org.springframework.data.mongodb.core.query;
|
||||
|
||||
import static org.hamcrest.CoreMatchers.*;
|
||||
import static org.junit.Assert.*;
|
||||
import static org.springframework.data.mongodb.test.util.IsBsonObject.*;
|
||||
|
||||
import org.junit.Test;
|
||||
import org.springframework.data.geo.Point;
|
||||
import org.springframework.data.mongodb.InvalidMongoDbApiUsageException;
|
||||
import org.springframework.data.mongodb.core.geo.GeoJsonLineString;
|
||||
import org.springframework.data.mongodb.core.geo.GeoJsonPoint;
|
||||
import org.springframework.data.mongodb.test.util.IsBsonObject;
|
||||
|
||||
import com.mongodb.BasicDBObject;
|
||||
import com.mongodb.BasicDBObjectBuilder;
|
||||
@@ -176,7 +177,7 @@ public class CriteriaTests {
|
||||
|
||||
DBObject dbo = new Criteria("foo").near(new GeoJsonPoint(100, 200)).getCriteriaObject();
|
||||
|
||||
assertThat(dbo, IsBsonObject.isBsonObject().containing("foo.$near.$geometry", new GeoJsonPoint(100, 200)));
|
||||
assertThat(dbo, isBsonObject().containing("foo.$near.$geometry", new GeoJsonPoint(100, 200)));
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -187,7 +188,7 @@ public class CriteriaTests {
|
||||
|
||||
DBObject dbo = new Criteria("foo").near(new Point(100, 200)).getCriteriaObject();
|
||||
|
||||
assertThat(dbo, IsBsonObject.isBsonObject().notContaining("foo.$near.$geometry"));
|
||||
assertThat(dbo, isBsonObject().notContaining("foo.$near.$geometry"));
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -198,7 +199,7 @@ public class CriteriaTests {
|
||||
|
||||
DBObject dbo = new Criteria("foo").near(new GeoJsonPoint(100, 200)).maxDistance(50D).getCriteriaObject();
|
||||
|
||||
assertThat(dbo, IsBsonObject.isBsonObject().containing("foo.$near.$maxDistance", 50D));
|
||||
assertThat(dbo, isBsonObject().containing("foo.$near.$maxDistance", 50D));
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -209,7 +210,7 @@ public class CriteriaTests {
|
||||
|
||||
DBObject dbo = new Criteria("foo").nearSphere(new GeoJsonPoint(100, 200)).maxDistance(50D).getCriteriaObject();
|
||||
|
||||
assertThat(dbo, IsBsonObject.isBsonObject().containing("foo.$nearSphere.$maxDistance", 50D));
|
||||
assertThat(dbo, isBsonObject().containing("foo.$nearSphere.$maxDistance", 50D));
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -220,7 +221,7 @@ public class CriteriaTests {
|
||||
|
||||
DBObject dbo = new Criteria("foo").near(new GeoJsonPoint(100, 200)).minDistance(50D).getCriteriaObject();
|
||||
|
||||
assertThat(dbo, IsBsonObject.isBsonObject().containing("foo.$near.$minDistance", 50D));
|
||||
assertThat(dbo, isBsonObject().containing("foo.$near.$minDistance", 50D));
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -231,7 +232,7 @@ public class CriteriaTests {
|
||||
|
||||
DBObject dbo = new Criteria("foo").nearSphere(new GeoJsonPoint(100, 200)).minDistance(50D).getCriteriaObject();
|
||||
|
||||
assertThat(dbo, IsBsonObject.isBsonObject().containing("foo.$nearSphere.$minDistance", 50D));
|
||||
assertThat(dbo, isBsonObject().containing("foo.$nearSphere.$minDistance", 50D));
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -243,8 +244,27 @@ public class CriteriaTests {
|
||||
DBObject dbo = new Criteria("foo").nearSphere(new GeoJsonPoint(100, 200)).minDistance(50D).maxDistance(100D)
|
||||
.getCriteriaObject();
|
||||
|
||||
assertThat(dbo, IsBsonObject.isBsonObject().containing("foo.$nearSphere.$minDistance", 50D));
|
||||
assertThat(dbo, IsBsonObject.isBsonObject().containing("foo.$nearSphere.$maxDistance", 100D));
|
||||
assertThat(dbo, isBsonObject().containing("foo.$nearSphere.$minDistance", 50D));
|
||||
assertThat(dbo, isBsonObject().containing("foo.$nearSphere.$maxDistance", 100D));
|
||||
}
|
||||
|
||||
/**
|
||||
* @see DATAMONGO-1134
|
||||
*/
|
||||
@Test(expected = IllegalArgumentException.class)
|
||||
public void intersectsShouldThrowExceptionWhenCalledWihtNullValue() {
|
||||
new Criteria("foo").intersects(null);
|
||||
}
|
||||
|
||||
/**
|
||||
* @see DATAMONGO-1134
|
||||
*/
|
||||
@Test
|
||||
public void intersectsShouldWrapGeoJsonTypeInGeometryCorrectly() {
|
||||
|
||||
GeoJsonLineString lineString = new GeoJsonLineString(new Point(0, 0), new Point(10, 10));
|
||||
DBObject dbo = new Criteria("foo").intersects(lineString).getCriteriaObject();
|
||||
|
||||
assertThat(dbo, isBsonObject().containing("foo.$geoIntersects.$geometry", lineString));
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user