Browse Source

DATADOC-87 - Created GeoSpatialIndexed annotation and modified index creation listener to create geospatial indexes. Also added test case for same.

pull/1/head
Jon Brisbin 15 years ago committed by J. Brisbin
parent
commit
ec6cec99b7
  1. 68
      spring-data-mongodb/src/main/java/org/springframework/data/document/mongodb/index/GeoSpatialIndexed.java
  2. 42
      spring-data-mongodb/src/main/java/org/springframework/data/document/mongodb/mapping/MongoPersistentEntityIndexCreator.java
  3. 81
      spring-data-mongodb/src/test/java/org/springframework/data/document/mongodb/mapping/GeoIndexedTests.java
  4. 50
      spring-data-mongodb/src/test/java/org/springframework/data/document/mongodb/mapping/GeoLocation.java

68
spring-data-mongodb/src/main/java/org/springframework/data/document/mongodb/index/GeoSpatialIndexed.java

@ -0,0 +1,68 @@ @@ -0,0 +1,68 @@
/*
* Copyright (c) 2011 by the original author(s).
*
* 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.document.mongodb.index;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
/**
* Mark a class property to be indexed using MongoDB's geospatial indexing feature.
*
* @author Jon Brisbin <jbrisbin@vmware.com>
*/
@Target(ElementType.FIELD)
@Retention(RetentionPolicy.RUNTIME)
public @interface GeoSpatialIndexed {
/**
* Name of the property in the document that contains the [x, y] or radial coordinates to index.
*
* @return
*/
String name() default "";
/**
* Name of the collection in which to create the index.
*
* @return
*/
String collection() default "";
/**
* Minimum value for indexed values.
*
* @return
*/
int min() default 0;
/**
* Maximum value for indexed values.
*
* @return
*/
int max() default 0;
/**
* Bits of precision for boundary calculations.
*
* @return
*/
int bits() default 26;
}

42
spring-data-mongodb/src/main/java/org/springframework/data/document/mongodb/mapping/MongoPersistentEntityIndexCreator.java

@ -34,6 +34,7 @@ import org.springframework.data.document.mongodb.CollectionCallback; @@ -34,6 +34,7 @@ import org.springframework.data.document.mongodb.CollectionCallback;
import org.springframework.data.document.mongodb.MongoTemplate;
import org.springframework.data.document.mongodb.index.CompoundIndex;
import org.springframework.data.document.mongodb.index.CompoundIndexes;
import org.springframework.data.document.mongodb.index.GeoSpatialIndexed;
import org.springframework.data.document.mongodb.index.IndexDirection;
import org.springframework.data.document.mongodb.index.Indexed;
import org.springframework.data.mapping.PropertyHandler;
@ -130,6 +131,20 @@ public class MongoPersistentEntityIndexCreator implements ApplicationListener<Ma @@ -130,6 +131,20 @@ public class MongoPersistentEntityIndexCreator implements ApplicationListener<Ma
if (log.isDebugEnabled()) {
log.debug("Created property index " + index);
}
} else if (field.isAnnotationPresent(GeoSpatialIndexed.class)) {
GeoSpatialIndexed index = field.getAnnotation(GeoSpatialIndexed.class);
String name = index.name();
if ("".equals(name)) {
name = field.getName();
}
String collection = index.collection();
if ("".equals(collection)) {
collection = entity.getCollection();
}
ensureGeoIndex(collection, name, index.min(), index.max(), index.bits());
if (log.isDebugEnabled()) {
log.debug("Created geo index " + index);
}
}
}
});
@ -167,4 +182,31 @@ public class MongoPersistentEntityIndexCreator implements ApplicationListener<Ma @@ -167,4 +182,31 @@ public class MongoPersistentEntityIndexCreator implements ApplicationListener<Ma
});
}
protected void ensureGeoIndex(String collection,
final String name,
final int min,
final int max,
final int bits) {
mongoTemplate.execute(collection, new CollectionCallback<Object>() {
public Object doInCollection(DBCollection collection) throws MongoException, DataAccessException {
DBObject defObj = new BasicDBObject();
defObj.put(name, "2d");
DBObject opts = new BasicDBObject();
// Min
if (min != 0) {
opts.put("min", min);
}
// Max
if (max != 0) {
opts.put("max", max);
}
// Bits
opts.put("bits", bits);
collection.ensureIndex(defObj, opts);
return null;
}
});
}
}

81
spring-data-mongodb/src/test/java/org/springframework/data/document/mongodb/mapping/GeoIndexedTests.java

@ -0,0 +1,81 @@ @@ -0,0 +1,81 @@
/*
* Copyright (c) 2011 by the original author(s).
*
* 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.document.mongodb.mapping;
import static org.junit.Assert.*;
import java.util.List;
import com.mongodb.DB;
import com.mongodb.DBCollection;
import com.mongodb.DBObject;
import com.mongodb.Mongo;
import com.mongodb.MongoException;
import org.junit.Before;
import org.junit.Test;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
import org.springframework.dao.DataAccessException;
import org.springframework.data.document.mongodb.CollectionCallback;
import org.springframework.data.document.mongodb.MongoTemplate;
/**
* @author Jon Brisbin <jbrisbin@vmware.com>
*/
public class GeoIndexedTests {
private final String[] collectionsToDrop = new String[]{
"geolocation"
};
ApplicationContext applicationContext;
MongoTemplate template;
MongoMappingContext mappingContext;
@Before
public void setUp() throws Exception {
Mongo mongo = new Mongo();
DB db = mongo.getDB("database");
for (String coll : collectionsToDrop) {
db.getCollection(coll).drop();
}
applicationContext = new ClassPathXmlApplicationContext("/mapping.xml");
template = applicationContext.getBean(MongoTemplate.class);
mappingContext = applicationContext.getBean(MongoMappingContext.class);
}
@Test
public void testGeoLocation() {
GeoLocation geo = new GeoLocation(new double[]{40.714346, -74.005966});
template.insert(geo);
boolean hasIndex = template.execute("geolocation", new CollectionCallback<Boolean>() {
public Boolean doInCollection(DBCollection collection) throws MongoException, DataAccessException {
List<DBObject> indexes = collection.getIndexInfo();
for (DBObject dbo : indexes) {
if ("location_2d".equals(dbo.get("name"))) {
return true;
}
}
return false;
}
});
assertTrue(hasIndex);
}
}

50
spring-data-mongodb/src/test/java/org/springframework/data/document/mongodb/mapping/GeoLocation.java

@ -0,0 +1,50 @@ @@ -0,0 +1,50 @@
/*
* Copyright (c) 2011 by the original author(s).
*
* 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.document.mongodb.mapping;
import org.bson.types.ObjectId;
import org.springframework.data.annotation.Id;
import org.springframework.data.document.mongodb.index.GeoSpatialIndexed;
/**
* @author Jon Brisbin <jbrisbin@vmware.com>
*/
@Document
public class GeoLocation {
@Id
private ObjectId id;
@GeoSpatialIndexed
private double[] location;
public GeoLocation(double[] location) {
this.location = location;
}
public ObjectId getId() {
return id;
}
public double[] getLocation() {
return location;
}
public void setLocation(double[] location) {
this.location = location;
}
}
Loading…
Cancel
Save