added indexing features to MongoTemplate

This commit is contained in:
Thomas Risberg
2011-02-12 16:12:51 -05:00
parent 222b1507cd
commit c47c7deeeb
10 changed files with 337 additions and 11 deletions

View File

@@ -18,6 +18,7 @@ package org.springframework.data.document.mongodb;
import java.util.List;
import java.util.Set;
import org.springframework.data.document.mongodb.query.Index;
import org.springframework.data.document.mongodb.query.Query;
import org.springframework.data.document.mongodb.query.Update;
@@ -204,6 +205,23 @@ public interface MongoOperations {
*/
<T> List<T> getCollection(String collectionName, Class<T> targetClass,
MongoReader<T> reader);
/**
* Ensure that an index for the specified {@link Index} specification exists for the default collection.
* If not is will be created.
*
* @param index
*/
void ensureIndex(Index index);
/**
* Ensure that an index for the specified {@link Index} specification exists. If not is will be
* created.
*
* @param collectionName
* @param index
*/
void ensureIndex(String collectionName, Index index);
/**
* Map the results of an ad-hoc query on the default MongoDB collection to a List of the specified type.

View File

@@ -30,6 +30,7 @@ import org.springframework.beans.factory.InitializingBean;
import org.springframework.dao.DataAccessException;
import org.springframework.dao.DataIntegrityViolationException;
import org.springframework.data.document.mongodb.MongoPropertyDescriptors.MongoPropertyDescriptor;
import org.springframework.data.document.mongodb.query.Index;
import org.springframework.data.document.mongodb.query.Query;
import org.springframework.data.document.mongodb.query.Update;
import org.springframework.jca.cci.core.ConnectionCallback;
@@ -406,6 +407,26 @@ public class MongoTemplate implements InitializingBean, MongoOperations {
}, collectionName);
}
// Indexing methods
public void ensureIndex(Index index) {
ensureIndex(getDefaultCollectionName(), index);
}
public void ensureIndex(String collectionName, final Index index) {
execute(new CollectionCallback<Object>() {
public Object doInCollection(DBCollection collection) throws MongoException, DataAccessException {
DBObject indexOptions = index.getIndexOptions();
if (indexOptions != null) {
collection.ensureIndex(index.getIndexObject(), indexOptions);
}
else {
collection.ensureIndex(index.getIndexObject());
}
return null;
}
}, collectionName);
}
// Find methods that take a Query to express the query.

View File

@@ -0,0 +1,77 @@
/*
* Copyright 2010-2011 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.document.mongodb.query;
import com.mongodb.BasicDBObject;
import com.mongodb.DBObject;
public class GeospatialIndex {
private String keyField;
private String name;
private Integer min = null;
private Integer max = null;
public GeospatialIndex() {
}
public GeospatialIndex(String key) {
keyField = key;
}
public GeospatialIndex named(String name) {
this.name = name;
return this;
}
public GeospatialIndex withMin(int min) {
this.min = Integer.valueOf(min);
return this;
}
public GeospatialIndex withMax(int max) {
this.max = Integer.valueOf(max);
return this;
}
public DBObject getIndexObject() {
DBObject dbo = new BasicDBObject();
dbo.put(keyField, "2d");
return dbo;
}
public DBObject getIndexOptions() {
if (name == null && min == null && max == null) {
return null;
}
DBObject dbo = new BasicDBObject();
if (name != null) {
dbo.put("name", name);
}
if (min != null) {
dbo.put("min", min);
}
if (max != null) {
dbo.put("max", max);
}
return dbo;
}
}

View File

@@ -0,0 +1,94 @@
/*
* Copyright 2010-2011 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.document.mongodb.query;
import java.util.HashMap;
import java.util.Map;
import com.mongodb.BasicDBObject;
import com.mongodb.DBObject;
public class Index {
public enum Duplicates {
RETAIN,
DROP
}
private Map<String, Order> fieldSpec = new HashMap<String, Order>();
private String name;
private boolean unique = false;
private boolean dropDuplicates = false;
public Index() {
}
public Index(String key, Order order) {
fieldSpec.put(key, order);
}
public Index on(String key, Order order) {
fieldSpec.put(key, order);
return this;
}
public Index named(String name) {
this.name = name;
return this;
}
public Index unique() {
this.unique = true;
return this;
}
public Index unique(Duplicates duplicates) {
if (duplicates == Duplicates.DROP) {
this.dropDuplicates = true;
}
return unique();
}
public DBObject getIndexObject() {
DBObject dbo = new BasicDBObject();
for (String k : fieldSpec.keySet()) {
dbo.put(k, (fieldSpec.get(k).equals(Order.ASCENDING) ? 1 : -1));
}
return dbo;
}
public DBObject getIndexOptions() {
if (name == null && !unique) {
return null;
}
DBObject dbo = new BasicDBObject();
if (name != null) {
dbo.put("name", name);
}
if (unique) {
dbo.put("unique", true);
}
if (dropDuplicates) {
dbo.put("drop_dups", true);
}
return dbo;
}
}

View File

@@ -0,0 +1,25 @@
/*
* Copyright 2010-2011 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.document.mongodb.query;
/**
* An enum that specifies the ordering for sort or index specifications
*
* @author trisberg
*/
public enum Order {
ASCENDING, DESCENDING
}

View File

@@ -24,21 +24,24 @@ import com.mongodb.DBObject;
public class Sort {
public enum Order {
ASCENDING, DESCENDING
private Map<String, Order> fieldSpec = new HashMap<String, Order>();
public Sort() {
}
private Map<String, Order> criteria = new HashMap<String, Order>();
public Sort(String key, Order order) {
fieldSpec.put(key, order);
}
public Sort on(String key, Order order) {
criteria.put(key, order);
fieldSpec.put(key, order);
return this;
}
public DBObject getSortObject() {
DBObject dbo = new BasicDBObject();
for (String k : criteria.keySet()) {
dbo.put(k, (criteria.get(k).equals(Order.ASCENDING) ? 1 : -1));
for (String k : fieldSpec.keySet()) {
dbo.put(k, (fieldSpec.get(k).equals(Order.ASCENDING) ? 1 : -1));
}
return dbo;
}

View File

@@ -78,8 +78,8 @@ abstract class QueryUtils {
for (Order order : sort) {
bSort.on(
order.getProperty(),
order.isAscending() ? org.springframework.data.document.mongodb.query.Sort.Order.ASCENDING
: org.springframework.data.document.mongodb.query.Sort.Order.DESCENDING);
order.isAscending() ? org.springframework.data.document.mongodb.query.Order.ASCENDING
: org.springframework.data.document.mongodb.query.Order.DESCENDING);
}
return query;

View File

@@ -32,11 +32,16 @@ import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.dao.DataIntegrityViolationException;
import org.springframework.data.document.mongodb.query.Criteria;
import org.springframework.data.document.mongodb.query.Index;
import org.springframework.data.document.mongodb.query.Index.Duplicates;
import org.springframework.data.document.mongodb.query.Order;
import org.springframework.data.document.mongodb.query.Query;
import org.springframework.data.document.mongodb.query.Update;
import org.springframework.test.context.ContextConfiguration;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
import com.mongodb.DBCollection;
import com.mongodb.DBObject;
import com.mongodb.WriteConcern;
/**
@@ -92,6 +97,38 @@ public class MongoTemplateTests {
}
@Test
public void testEnsureIndex() throws Exception {
Person p1 = new Person("Oliver");
p1.setAge(25);
template.insert(p1);
Person p2 = new Person("Sven");
p2.setAge(40);
template.insert(p2);
template.ensureIndex(new Index().on("age", Order.DESCENDING).unique(Duplicates.DROP));
DBCollection coll = template.getCollection(template.getDefaultCollectionName());
List<DBObject> indexInfo = coll.getIndexInfo();
assertThat(indexInfo.size(), is(2));
String indexKey = null;
boolean unique = false;
boolean dropDupes = false;
for (DBObject ix : indexInfo) {
System.out.println(ix);
if ("age_-1".equals(ix.get("name"))) {
indexKey = ix.get("key").toString();
unique = (Boolean) ix.get("unique");
dropDupes = (Boolean) ix.get("drop_dups");
}
}
assertThat(indexKey, is("{ \"age\" : -1}"));
assertThat(unique, is(true));
assertThat(dropDupes, is(true));
}
@Test
public void simpleQuery() throws Exception {
new Query(where("name").is("Mary")).and(where("age").lt(33).gt(22)).skip(22).limit(20);

View File

@@ -0,0 +1,51 @@
/*
* Copyright 2010-2011 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.document.mongodb.query;
import org.junit.Assert;
import org.junit.Test;
import org.springframework.data.document.mongodb.query.Index.Duplicates;
public class IndexTests {
@Test
public void testWithAscendingIndex() {
Index i = new Index().on("name", Order.ASCENDING);
Assert.assertEquals("{ \"name\" : 1}", i.getIndexObject().toString());
}
@Test
public void testWithDescendingIndex() {
Index i = new Index().on("name", Order.DESCENDING);
Assert.assertEquals("{ \"name\" : -1}", i.getIndexObject().toString());
}
@Test
public void testNamedMultiFieldUniqueIndex() {
Index i = new Index().on("name", Order.ASCENDING).on("age", Order.DESCENDING);
i.named("test").unique();
Assert.assertEquals("{ \"age\" : -1 , \"name\" : 1}", i.getIndexObject().toString());
Assert.assertEquals("{ \"name\" : \"test\" , \"unique\" : true}", i.getIndexOptions().toString());
}
@Test
public void testWithDropDuplicates() {
Index i = new Index().on("name", Order.ASCENDING);
i.unique(Duplicates.DROP);
Assert.assertEquals("{ \"name\" : 1}", i.getIndexObject().toString());
Assert.assertEquals("{ \"unique\" : true , \"drop_dups\" : true}", i.getIndexOptions().toString());
}
}

View File

@@ -18,7 +18,7 @@ package org.springframework.data.document.mongodb.query;
import org.junit.Assert;
import org.junit.Test;
import org.springframework.data.document.mongodb.query.Sort;
import org.springframework.data.document.mongodb.query.Sort.Order;
import org.springframework.data.document.mongodb.query.Order;
public class SortTests {