From 41e60e5c25f3d9b67c08baef9b18676cdbafc660 Mon Sep 17 00:00:00 2001 From: Dave Perryman Date: Tue, 9 Apr 2019 15:20:55 +0100 Subject: [PATCH] DATAMONGO-1569 - Add support for partial filter expressions in compound index annotations Original Pull Request: #738 --- .../mongodb/core/index/CompoundIndex.java | 10 ++++++++ .../MongoPersistentEntityIndexResolver.java | 5 ++++ ...ersistentEntityIndexResolverUnitTests.java | 23 ++++++++++++++++++- 3 files changed, 37 insertions(+), 1 deletion(-) 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 3141ba349..b6808dd8f 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 Philipp Schneider * @author Johno Crawford * @author Christoph Strobl + * @author Dave Perryman */ @Target({ ElementType.TYPE }) @Documented @@ -170,4 +171,13 @@ public @interface CompoundIndex { */ boolean background() default false; + + /** + * Only index the documents in a collection that meet a specified {@link IndexFilter filter expression}. + * + * @return + * @see https://docs.mongodb.com/manual/core/index-partial/ + */ + String partial() 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 ac5d22413..0c63d6551 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 @@ -69,6 +69,7 @@ import org.springframework.util.StringUtils; * @author Thomas Darimont * @author Martin Macko * @author Mark Paluch + * @author Dave Perryman * @since 1.5 */ public class MongoPersistentEntityIndexResolver implements IndexResolver { @@ -380,6 +381,10 @@ public class MongoPersistentEntityIndexResolver implements IndexResolver { indexDefinition.background(); } + if (StringUtils.hasText(index.partial())) { + indexDefinition.partial(PartialIndexFilter.of(org.bson.Document.parse(index.partial()))); + } + return new IndexDefinitionHolder(dotPath, indexDefinition, collection); } 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 cd6de29f3..7630cb70d 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 @@ -25,7 +25,7 @@ import java.lang.annotation.Target; import java.util.Collections; import java.util.List; -import org.junit.jupiter.api.Test; +import org.junit.Test; import org.junit.runner.RunWith; import org.junit.runners.Suite; import org.junit.runners.Suite.SuiteClasses; @@ -54,6 +54,7 @@ import org.springframework.data.util.ClassTypeInformation; * * @author Christoph Strobl * @author Mark Paluch + * @author Dave Perryman */ @RunWith(Suite.class) @SuiteClasses({ IndexResolutionTests.class, GeoSpatialIndexResolutionTests.class, CompoundIndexResolutionTests.class, @@ -663,6 +664,21 @@ public class MongoPersistentEntityIndexResolverUnitTests { indexDefinitions.get(1)); } + @Test // DATAMONGO-1569 + public void singleIndexWithPartialFilter() { + + List indexDefinitions = prepareMappingContextAndResolveIndexForType( + SingleCompoundIndexWithPartialFilter.class); + + assertThat(indexDefinitions).hasSize(1); + assertThat(indexDefinitions.get(0).getIndexKeys()).containsEntry("foo", 1).containsEntry("bar", -1); + assertThat(indexDefinitions.get(0).getIndexOptions()).containsEntry("name", "compound_index_with_partial") + .containsEntry("unique", true).containsEntry("background", true); + assertThat(indexDefinitions.get(0).getIndexOptions()).containsEntry("partialFilterExpression", + new org.bson.Document().append("bar", new org.bson.Document().append("$exists", true))); + } + + @Document("CompoundIndexOnLevelOne") static class CompoundIndexOnLevelOne { @@ -733,6 +749,11 @@ public class MongoPersistentEntityIndexResolverUnitTests { @CompoundIndex(name = "cmp-idx-one", def = "{'firstname': 1, 'lastname': -1}") @CompoundIndex(name = "cmp-idx-two", def = "{'address.city': -1, 'address.street': 1}") static class RepeatedCompoundIndex {} + + @Document("SingleCompoundIndexWithPartialFilter") + @CompoundIndex(name = "compound_index_with_partial", def = "{'foo': 1, 'bar': -1}", background = true, + unique = true, partial = "{'bar': {$exists: true}}") + static class SingleCompoundIndexWithPartialFilter {} } public static class TextIndexedResolutionTests {