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 ebaa3a96e..8f2199c93 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
@@ -53,7 +53,8 @@ public @interface Indexed {
IndexDirection direction() default IndexDirection.ASCENDING;
/**
- * If set to true index will skip over any document that is missing the indexed field.
+ * If set to true index will skip over any document that is missing the indexed field.
+ * Must not be used with {@link #partialFilter()}.
*
* @return {@literal false} by default.
* @see
+ * Must not be used with {@link #sparse() sparse = true}.
+ *
+ * @return empty by default.
+ * @see https://docs.mongodb.com/manual/core/index-partial/
+ * @since 3.1
+ */
+ String partialFilter() 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 0c63d6551..aa3578bad 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
@@ -46,6 +46,7 @@ import org.springframework.data.mongodb.core.mapping.BasicMongoPersistentEntity;
import org.springframework.data.mongodb.core.mapping.Document;
import org.springframework.data.mongodb.core.mapping.MongoPersistentEntity;
import org.springframework.data.mongodb.core.mapping.MongoPersistentProperty;
+import org.springframework.data.mongodb.util.BsonUtils;
import org.springframework.data.spel.EvaluationContextProvider;
import org.springframework.data.util.TypeInformation;
import org.springframework.expression.EvaluationContext;
@@ -474,9 +475,25 @@ public class MongoPersistentEntityIndexResolver implements IndexResolver {
}
}
+ if (StringUtils.hasText(index.partialFilter())) {
+ indexDefinition.partial(evaluatePartialFilter(index.partialFilter(), persistentProperty.getOwner()));
+ }
+
return new IndexDefinitionHolder(dotPath, indexDefinition, collection);
}
+ private PartialIndexFilter evaluatePartialFilter(String filterExpression, PersistentEntity,?> entity) {
+
+ Object result = evaluate(filterExpression, getEvaluationContextForProperty(entity));
+
+ if (result instanceof org.bson.Document) {
+ return PartialIndexFilter.of((org.bson.Document) result);
+ }
+
+ return PartialIndexFilter.of(BsonUtils.parse(filterExpression, null));
+ }
+
+
/**
* Creates {@link HashedIndex} wrapped in {@link IndexDefinitionHolder} out of {@link HashIndexed} for a given
* {@link MongoPersistentProperty}.
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 7630cb70d..fbddbdbb3 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
@@ -271,6 +271,16 @@ public class MongoPersistentEntityIndexResolverUnitTests {
assertThat(indexDefinitions.get(0).getIndexOptions()).containsEntry("name", "my1st");
}
+ @Test // DATAMONGO-1569
+ public void resolvesPartialFilter() {
+
+ List indexDefinitions = prepareMappingContextAndResolveIndexForType(
+ WithPartialFilter.class);
+
+ assertThat(indexDefinitions.get(0).getIndexOptions()).containsEntry("partialFilterExpression",
+ org.bson.Document.parse("{'value': {'$exists': true}}"));
+ }
+
@Document("Zero")
static class IndexOnLevelZero {
@Indexed String indexedProperty;
@@ -395,6 +405,11 @@ public class MongoPersistentEntityIndexResolverUnitTests {
static class WithIndexNameAsExpression {
@Indexed(name = "#{'my' + 1 + 'st'}") String spelIndexName;
}
+
+ @Document
+ class WithPartialFilter {
+ @Indexed(partialFilter = "{'value': {'$exists': true}}") String withPartialFilter;
+ }
}
@Target({ ElementType.FIELD })