Browse Source

DATAMONGO-483 - Indexes now use the field name even if index name is defined.

1.0.x
Oliver Gierke 14 years ago
parent
commit
a82fbade95
  1. 35
      spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/index/CompoundIndex.java
  2. 52
      spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/index/MongoPersistentEntityIndexCreator.java
  3. 82
      spring-data-mongodb/src/test/java/org/springframework/data/mongodb/core/index/MongoPersistentEntityIndexCreatorUnitTests.java

35
spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/index/CompoundIndex.java

@ -1,11 +1,11 @@
/* /*
* Copyright (c) 2011 by the original author(s). * Copyright 2011-2012 the original author or authors.
* *
* Licensed under the Apache License, Version 2.0 (the "License"); * Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License. * you may not use this file except in compliance with the License.
* You may obtain a copy of the License at * You may obtain a copy of the License at
* *
* http://www.apache.org/licenses/LICENSE-2.0 * http://www.apache.org/licenses/LICENSE-2.0
* *
* Unless required by applicable law or agreed to in writing, software * Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS, * distributed under the License is distributed on an "AS IS" BASIS,
@ -13,9 +13,9 @@
* See the License for the specific language governing permissions and * See the License for the specific language governing permissions and
* limitations under the License. * limitations under the License.
*/ */
package org.springframework.data.mongodb.core.index; package org.springframework.data.mongodb.core.index;
import java.lang.annotation.Documented;
import java.lang.annotation.ElementType; import java.lang.annotation.ElementType;
import java.lang.annotation.Retention; import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy; import java.lang.annotation.RetentionPolicy;
@ -24,14 +24,29 @@ import java.lang.annotation.Target;
/** /**
* Mark a class to use compound indexes. * Mark a class to use compound indexes.
* *
* @author Jon Brisbin <jbrisbin@vmware.com> * @author Jon Brisbin
* @author Oliver Gierke
*/ */
@Target({ ElementType.TYPE }) @Target({ ElementType.TYPE })
@Documented
@Retention(RetentionPolicy.RUNTIME) @Retention(RetentionPolicy.RUNTIME)
public @interface CompoundIndex { public @interface CompoundIndex {
/**
* The actual index definition in JSON format. The keys of the JSON document are the fields to be indexed, the values
* define the index direction (1 for ascending, -1 for descending).
*
* @return
*/
String def(); String def();
/**
* It does not actually make sense to use that attribute as the direction has to be defined in the {@link #def()}
* attribute actually.
*
* @return
*/
@Deprecated
IndexDirection direction() default IndexDirection.ASCENDING; IndexDirection direction() default IndexDirection.ASCENDING;
boolean unique() default false; boolean unique() default false;
@ -40,8 +55,18 @@ public @interface CompoundIndex {
boolean dropDups() default false; boolean dropDups() default false;
/**
* The name of the index to be created.
*
* @return
*/
String name() default ""; String name() default "";
/**
* The collection the index will be created in. Will default to the collection the annotated domain class will be
* stored in.
*
* @return
*/
String collection() default ""; String collection() default "";
} }

52
spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/index/MongoPersistentEntityIndexCreator.java

@ -1,11 +1,11 @@
/* /*
* Copyright (c) 2011 by the original author(s). * Copyright 2011-2012 the original author or authors.
* *
* Licensed under the Apache License, Version 2.0 (the "License"); * Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License. * you may not use this file except in compliance with the License.
* You may obtain a copy of the License at * You may obtain a copy of the License at
* *
* http://www.apache.org/licenses/LICENSE-2.0 * http://www.apache.org/licenses/LICENSE-2.0
* *
* Unless required by applicable law or agreed to in writing, software * Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS, * distributed under the License is distributed on an "AS IS" BASIS,
@ -13,7 +13,6 @@
* See the License for the specific language governing permissions and * See the License for the specific language governing permissions and
* limitations under the License. * limitations under the License.
*/ */
package org.springframework.data.mongodb.core.index; package org.springframework.data.mongodb.core.index;
import java.lang.reflect.Field; import java.lang.reflect.Field;
@ -27,7 +26,6 @@ import org.springframework.data.mapping.PersistentEntity;
import org.springframework.data.mapping.PropertyHandler; import org.springframework.data.mapping.PropertyHandler;
import org.springframework.data.mapping.event.MappingContextEvent; import org.springframework.data.mapping.event.MappingContextEvent;
import org.springframework.data.mongodb.MongoDbFactory; import org.springframework.data.mongodb.MongoDbFactory;
import org.springframework.data.mongodb.core.mapping.BasicMongoPersistentEntity;
import org.springframework.data.mongodb.core.mapping.MongoMappingContext; import org.springframework.data.mongodb.core.mapping.MongoMappingContext;
import org.springframework.data.mongodb.core.mapping.MongoPersistentEntity; import org.springframework.data.mongodb.core.mapping.MongoPersistentEntity;
import org.springframework.data.mongodb.core.mapping.MongoPersistentProperty; import org.springframework.data.mongodb.core.mapping.MongoPersistentProperty;
@ -39,10 +37,10 @@ import com.mongodb.DBObject;
import com.mongodb.util.JSON; import com.mongodb.util.JSON;
/** /**
* Component that inspects {@link BasicMongoPersistentEntity} instances contained in the given * Component that inspects {@link MongoPersistentEntity} instances contained in the given {@link MongoMappingContext}
* {@link MongoMappingContext} for indexing metadata and ensures the indexes to be available. * for indexing metadata and ensures the indexes to be available.
* *
* @author Jon Brisbin <jbrisbin@vmware.com> * @author Jon Brisbin
* @author Oliver Gierke * @author Oliver Gierke
*/ */
public class MongoPersistentEntityIndexCreator implements public class MongoPersistentEntityIndexCreator implements
@ -97,12 +95,12 @@ public class MongoPersistentEntityIndexCreator implements
if (type.isAnnotationPresent(CompoundIndexes.class)) { if (type.isAnnotationPresent(CompoundIndexes.class)) {
CompoundIndexes indexes = type.getAnnotation(CompoundIndexes.class); CompoundIndexes indexes = type.getAnnotation(CompoundIndexes.class);
for (CompoundIndex index : indexes.value()) { for (CompoundIndex index : indexes.value()) {
String indexColl = index.collection();
if ("".equals(indexColl)) { String indexColl = StringUtils.hasText(index.collection()) ? index.collection() : entity.getCollection();
indexColl = entity.getCollection(); DBObject definition = (DBObject) JSON.parse(index.def());
}
ensureIndex(indexColl, index.name(), index.def(), index.direction(), index.unique(), index.dropDups(), ensureIndex(indexColl, index.name(), definition, index.unique(), index.dropDups(), index.sparse());
index.sparse());
if (log.isDebugEnabled()) { if (log.isDebugEnabled()) {
log.debug("Created compound index " + index); log.debug("Created compound index " + index);
} }
@ -111,10 +109,14 @@ public class MongoPersistentEntityIndexCreator implements
entity.doWithProperties(new PropertyHandler<MongoPersistentProperty>() { entity.doWithProperties(new PropertyHandler<MongoPersistentProperty>() {
public void doWithPersistentProperty(MongoPersistentProperty persistentProperty) { public void doWithPersistentProperty(MongoPersistentProperty persistentProperty) {
Field field = persistentProperty.getField(); Field field = persistentProperty.getField();
if (field.isAnnotationPresent(Indexed.class)) { if (field.isAnnotationPresent(Indexed.class)) {
Indexed index = field.getAnnotation(Indexed.class); Indexed index = field.getAnnotation(Indexed.class);
String name = index.name(); String name = index.name();
if (!StringUtils.hasText(name)) { if (!StringUtils.hasText(name)) {
name = persistentProperty.getFieldName(); name = persistentProperty.getFieldName();
} else { } else {
@ -126,11 +128,17 @@ public class MongoPersistentEntityIndexCreator implements
} }
} }
} }
String collection = StringUtils.hasText(index.collection()) ? index.collection() : entity.getCollection(); String collection = StringUtils.hasText(index.collection()) ? index.collection() : entity.getCollection();
ensureIndex(collection, name, null, index.direction(), index.unique(), index.dropDups(), index.sparse()); int direction = index.direction() == IndexDirection.ASCENDING ? 1 : -1;
DBObject definition = new BasicDBObject(persistentProperty.getFieldName(), direction);
ensureIndex(collection, name, definition, index.unique(), index.dropDups(), index.sparse());
if (log.isDebugEnabled()) { if (log.isDebugEnabled()) {
log.debug("Created property index " + index); log.debug("Created property index " + index);
} }
} else if (field.isAnnotationPresent(GeoSpatialIndexed.class)) { } else if (field.isAnnotationPresent(GeoSpatialIndexed.class)) {
GeoSpatialIndexed index = field.getAnnotation(GeoSpatialIndexed.class); GeoSpatialIndexed index = field.getAnnotation(GeoSpatialIndexed.class);
@ -155,21 +163,15 @@ public class MongoPersistentEntityIndexCreator implements
} }
} }
protected void ensureIndex(String collection, final String name, final String def, final IndexDirection direction, protected void ensureIndex(String collection, String name, DBObject indexDefinition, boolean unique,
final boolean unique, final boolean dropDups, final boolean sparse) { boolean dropDups, boolean sparse) {
DBObject defObj;
if (null != def) {
defObj = (DBObject) JSON.parse(def);
} else {
defObj = new BasicDBObject();
defObj.put(name, (direction == IndexDirection.ASCENDING ? 1 : -1));
}
DBObject opts = new BasicDBObject(); DBObject opts = new BasicDBObject();
opts.put("name", name); opts.put("name", name);
opts.put("dropDups", dropDups); opts.put("dropDups", dropDups);
opts.put("sparse", sparse); opts.put("sparse", sparse);
opts.put("unique", unique); opts.put("unique", unique);
mongoDbFactory.getDb().getCollection(collection).ensureIndex(defObj, opts);
}
mongoDbFactory.getDb().getCollection(collection).ensureIndex(indexDefinition, opts);
}
} }

82
spring-data-mongodb/src/test/java/org/springframework/data/mongodb/core/index/MongoPersistentEntityIndexCreatorUnitTests.java

@ -0,0 +1,82 @@
/*
* Copyright 2012 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.mongodb.core.index;
import static org.hamcrest.CoreMatchers.*;
import static org.junit.Assert.*;
import java.util.Collections;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.mockito.Mock;
import org.mockito.runners.MockitoJUnitRunner;
import org.springframework.data.mongodb.MongoDbFactory;
import org.springframework.data.mongodb.core.mapping.Field;
import org.springframework.data.mongodb.core.mapping.MongoMappingContext;
import com.mongodb.DBObject;
/**
* Unit tests for {@link MongoPersistentEntityIndexCreator}.
*
* @author Oliver Gierke
*/
@RunWith(MockitoJUnitRunner.class)
public class MongoPersistentEntityIndexCreatorUnitTests {
@Mock
MongoDbFactory factory;
@Test
public void buildsIndexDefinitionUsingFieldName() {
MongoMappingContext mappingContext = new MongoMappingContext();
mappingContext.setInitialEntitySet(Collections.singleton(Person.class));
mappingContext.afterPropertiesSet();
DummyMongoPersistentEntityIndexCreator creator = new DummyMongoPersistentEntityIndexCreator(mappingContext, factory);
assertThat(creator.indexDefinition, is(notNullValue()));
assertThat(creator.indexDefinition.keySet(), hasItem("fieldname"));
assertThat(creator.name, is("indexName"));
}
static class Person {
@Indexed(name = "indexName")
@Field("fieldname")
String field;
}
static class DummyMongoPersistentEntityIndexCreator extends MongoPersistentEntityIndexCreator {
DBObject indexDefinition;
String name;
public DummyMongoPersistentEntityIndexCreator(MongoMappingContext mappingContext, MongoDbFactory mongoDbFactory) {
super(mappingContext, mongoDbFactory);
}
@Override
protected void ensureIndex(String collection, String name, DBObject indexDefinition, boolean unique,
boolean dropDups, boolean sparse) {
this.name = name;
this.indexDefinition = indexDefinition;
}
}
}
Loading…
Cancel
Save