DATADOC-87 - Created GeoSpatialIndexed annotation and modified index creation listener to create geospatial indexes. Also added test case for same.
This commit is contained in:
@@ -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;
|
||||
|
||||
}
|
||||
@@ -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
|
||||
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
|
||||
});
|
||||
}
|
||||
|
||||
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;
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
}
|
||||
Reference in New Issue
Block a user