DATAMONGO-1569 - Add partialFilter to Indexed annotation.

This commit is contained in:
Christoph Strobl
2020-06-18 15:02:58 +02:00
parent e6d47ce5b5
commit 4b2bc52ffc
3 changed files with 45 additions and 1 deletions

View File

@@ -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. <br />
* Must not be used with {@link #partialFilter()}.
*
* @return {@literal false} by default.
* @see <a href=
@@ -170,4 +171,15 @@ public @interface Indexed {
* @since 2.2
*/
String expireAfter() default "";
/**
* Only index the documents in a collection that meet a specified {@link IndexFilter filter expression}. <br />
* Must not be used with {@link #sparse() sparse = true}.
*
* @return empty by default.
* @see <a href=
* "https://docs.mongodb.com/manual/core/index-partial/">https://docs.mongodb.com/manual/core/index-partial/</a>
* @since 3.1
*/
String partialFilter() default "";
}

View File

@@ -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}.

View File

@@ -271,6 +271,16 @@ public class MongoPersistentEntityIndexResolverUnitTests {
assertThat(indexDefinitions.get(0).getIndexOptions()).containsEntry("name", "my1st");
}
@Test // DATAMONGO-1569
public void resolvesPartialFilter() {
List<IndexDefinitionHolder> 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 })