diff --git a/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/index/CompoundIndex.java b/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/index/CompoundIndex.java
index 138801506..7f2ee8403 100644
--- a/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/index/CompoundIndex.java
+++ b/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/index/CompoundIndex.java
@@ -46,6 +46,7 @@ import java.lang.annotation.Target;
* @author Johno Crawford
* @author Christoph Strobl
* @author Dave Perryman
+ * @author Stefan Tirea
*/
@Target({ ElementType.TYPE })
@Documented
@@ -163,4 +164,19 @@ public @interface CompoundIndex {
* @since 3.1
*/
String partialFilter() default "";
+
+ /**
+ * The actual collation definition in JSON format or a {@link org.springframework.expression.spel.standard.SpelExpression
+ * template expression} resolving to either a JSON String or a {@link org.bson.Document}. The keys of the JSON
+ * document are configuration options for the collation (language-specific rules for string comparison).
+ *
+ * TODO write code documentation & example!!!
+ *
+ *
+ * @return empty String by default.
+ * @see https://www.mongodb.com/docs/manual/reference/collation/
+ * @since 3.4
+ */
+ String collation() default "";
}
diff --git a/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/index/Indexed.java b/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/index/Indexed.java
index 3b41a4d80..ca82e95dc 100644
--- a/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/index/Indexed.java
+++ b/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/index/Indexed.java
@@ -31,6 +31,7 @@ import java.lang.annotation.Target;
* @author Christoph Strobl
* @author Jordi Llach
* @author Mark Paluch
+ * @author Stefan Tirea
*/
@Target({ ElementType.ANNOTATION_TYPE, ElementType.FIELD })
@Retention(RetentionPolicy.RUNTIME)
@@ -173,4 +174,14 @@ public @interface Indexed {
* @since 3.1
*/
String partialFilter() default "";
+
+ /**
+ * Apply collation configuration for field
+ *
+ * @return empty by default.
+ * @see https://www.mongodb.com/docs/manual/reference/collation//
+ * @since 3.1
+ */
+ String collation() default "";
}
diff --git a/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/index/MongoPersistentEntityIndexResolver.java b/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/index/MongoPersistentEntityIndexResolver.java
index a6424161e..4e4f308c6 100644
--- a/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/index/MongoPersistentEntityIndexResolver.java
+++ b/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/index/MongoPersistentEntityIndexResolver.java
@@ -74,6 +74,7 @@ import org.springframework.util.StringUtils;
* @author Martin Macko
* @author Mark Paluch
* @author Dave Perryman
+ * @author Stefan Tirea
* @since 1.5
*/
public class MongoPersistentEntityIndexResolver implements IndexResolver {
@@ -453,6 +454,10 @@ public class MongoPersistentEntityIndexResolver implements IndexResolver {
indexDefinition.partial(evaluatePartialFilter(index.partialFilter(), entity));
}
+ if (StringUtils.hasText(index.collation())) {
+ indexDefinition.collation(Collation.parse(index.collation()));
+ }
+
return new IndexDefinitionHolder(dotPath, indexDefinition, collection);
}
@@ -572,6 +577,10 @@ public class MongoPersistentEntityIndexResolver implements IndexResolver {
indexDefinition.partial(evaluatePartialFilter(index.partialFilter(), persistentProperty.getOwner()));
}
+ if (StringUtils.hasText(index.collation())) {
+ indexDefinition.collation(Collation.parse(index.collation()));
+ }
+
return new IndexDefinitionHolder(dotPath, indexDefinition, collection);
}
diff --git a/spring-data-mongodb/src/test/java/org/springframework/data/mongodb/core/index/IndexInfoUnitTests.java b/spring-data-mongodb/src/test/java/org/springframework/data/mongodb/core/index/IndexInfoUnitTests.java
index 2a5f0fb57..f0d642911 100644
--- a/spring-data-mongodb/src/test/java/org/springframework/data/mongodb/core/index/IndexInfoUnitTests.java
+++ b/spring-data-mongodb/src/test/java/org/springframework/data/mongodb/core/index/IndexInfoUnitTests.java
@@ -29,6 +29,7 @@ import org.springframework.data.domain.Sort.Direction;
*
* @author Oliver Gierke
* @author Christoph Strobl
+ * @author Stefan Tirea
*/
public class IndexInfoUnitTests {
@@ -37,6 +38,7 @@ public class IndexInfoUnitTests {
static final String INDEX_WITH_EXPIRATION_TIME = "{ \"v\" : 2, \"key\" : { \"lastModifiedDate\" : 1 },\"name\" : \"expire-after-last-modified\", \"ns\" : \"db.collectio\", \"expireAfterSeconds\" : 3600 }";
static final String HASHED_INDEX = "{ \"v\" : 2, \"key\" : { \"score\" : \"hashed\" }, \"name\" : \"score_hashed\", \"ns\" : \"db.collection\" }";
static final String WILDCARD_INDEX = "{ \"v\" : 2, \"key\" : { \"$**\" : 1 }, \"name\" : \"$**_1\", \"wildcardProjection\" : { \"fieldA\" : 0, \"fieldB.fieldC\" : 0 } }";
+ static final String INDEX_WITH_COLLATION = "{ \"v\" : 2, \"key\" : { \"_id\" : 1 }, \"name\" : \"projectName\", \"collation\": { \"locale\": \"en_US\", \"strength\": 2 } }";
@Test
public void isIndexForFieldsCorrectly() {
@@ -87,7 +89,14 @@ public class IndexInfoUnitTests {
@Test // GH-3225
public void readsWildcardIndexProjectionCorrectly() {
- assertThat(getIndexInfo(WILDCARD_INDEX).getWildcardProjection()).contains(new Document("fieldA", 0).append("fieldB.fieldC", 0));
+ assertThat(getIndexInfo(WILDCARD_INDEX).getWildcardProjection())
+ .contains(new Document("fieldA", 0).append("fieldB.fieldC", 0));
+ }
+
+ @Test // DATAMONGO-2133
+ public void collationParsedCorrectly() {
+ assertThat(getIndexInfo(INDEX_WITH_COLLATION).getCollation())
+ .contains(Document.parse("{ \"locale\": \"en_US\", \"strength\": 2 }"));
}
private static IndexInfo getIndexInfo(String documentJson) {
diff --git a/spring-data-mongodb/src/test/java/org/springframework/data/mongodb/core/index/MongoPersistentEntityIndexResolverUnitTests.java b/spring-data-mongodb/src/test/java/org/springframework/data/mongodb/core/index/MongoPersistentEntityIndexResolverUnitTests.java
index e7ce8d168..3e4e4226b 100644
--- a/spring-data-mongodb/src/test/java/org/springframework/data/mongodb/core/index/MongoPersistentEntityIndexResolverUnitTests.java
+++ b/spring-data-mongodb/src/test/java/org/springframework/data/mongodb/core/index/MongoPersistentEntityIndexResolverUnitTests.java
@@ -61,6 +61,7 @@ import org.springframework.data.util.ClassTypeInformation;
* @author Christoph Strobl
* @author Mark Paluch
* @author Dave Perryman
+ * @author Stefan Tirea
*/
@RunWith(Suite.class)
@SuiteClasses({ IndexResolutionTests.class, GeoSpatialIndexResolutionTests.class, CompoundIndexResolutionTests.class,
@@ -699,6 +700,19 @@ public class MongoPersistentEntityIndexResolverUnitTests {
org.bson.Document.parse("{'value': {'$exists': true}}"));
}
+ @Test // DATAMONGO-2133
+ public void compoundIndexWithCollation() {
+
+ List indexDefinitions = prepareMappingContextAndResolveIndexForType(
+ CompoundIndexWithCollation.class);
+
+ IndexDefinition indexDefinition = indexDefinitions.get(0).getIndexDefinition();
+ assertThat(indexDefinition.getIndexOptions())
+ .isEqualTo(new org.bson.Document().append("name", "compound_index_with_collation").append("collation",
+ new org.bson.Document().append("locale", "en_US").append("strength", 2)));
+ assertThat(indexDefinition.getIndexKeys()).isEqualTo(new org.bson.Document().append("foo", 1));
+ }
+
@Document("CompoundIndexOnLevelOne")
class CompoundIndexOnLevelOne {
@@ -774,6 +788,11 @@ public class MongoPersistentEntityIndexResolverUnitTests {
@CompoundIndex(name = "compound_index_with_partial", def = "{'foo': 1, 'bar': -1}", background = true,
unique = true, partialFilter = "{'value': {'$exists': true}}")
class SingleCompoundIndexWithPartialFilter {}
+
+ @Document
+ @CompoundIndex(name = "compound_index_with_collation", def = "{'foo': 1}",
+ collation = "{'locale': 'en_US', 'strength': 2}")
+ class CompoundIndexWithCollation {}
}
public static class TextIndexedResolutionTests {
@@ -1400,6 +1419,18 @@ public class MongoPersistentEntityIndexResolverUnitTests {
assertThat(indexDefinitions).hasSize(1);
}
+ @Test // DATAMONGO-2133
+ public void indexedWithCollation() {
+
+ List indexDefinitions = prepareMappingContextAndResolveIndexForType(
+ IndexedWithCollation.class);
+
+ IndexDefinition indexDefinition = indexDefinitions.get(0).getIndexDefinition();
+ assertThat(indexDefinition.getIndexOptions()).isEqualTo(new org.bson.Document().append("name", "value")
+ .append("unique", true)
+ .append("collation", new org.bson.Document().append("locale", "en_US").append("strength", 2)));
+ }
+
@Document
class MixedIndexRoot {
@@ -1717,6 +1748,12 @@ public class MongoPersistentEntityIndexResolverUnitTests {
@ComposedHashIndexed(name = "idx-name") String value;
}
+ @Document
+ class IndexedWithCollation {
+ @Indexed(collation = "{'locale': 'en_US', 'strength': 2}", unique = true) //
+ private String value;
+ }
+
@HashIndexed
@Indexed
@Retention(RetentionPolicy.RUNTIME)