diff --git a/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/aggregation/DocumentOperators.java b/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/aggregation/DocumentOperators.java index 8ba7acc5b..7a5918e04 100644 --- a/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/aggregation/DocumentOperators.java +++ b/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/aggregation/DocumentOperators.java @@ -18,6 +18,8 @@ package org.springframework.data.mongodb.core.aggregation; import org.bson.Document; /** + * Gateway to {@literal document expressions} such as {@literal $rank, $documentNumber, etc.} + * * @author Christoph Strobl * @since 3.3 */ @@ -43,6 +45,16 @@ public class DocumentOperators { return new DenseRank(); } + /** + * Obtain the current document position. + * + * @return new instance of {@link DocumentNumber}. + * @since 3.3 + */ + public static DocumentNumber documentNumber() { + return new DocumentNumber(); + } + /** * {@link Rank} resolves the current document position (the rank) relative to other documents. If multiple documents * occupy the same rank, {@literal $rank} places the document with the subsequent value at a rank with a gap. @@ -73,4 +85,18 @@ public class DocumentOperators { return new Document("$denseRank", new Document()); } } + + /** + * {@link DocumentNumber} resolves the current document position. + * + * @author Christoph Strobl + * @since 3.3 + */ + public static class DocumentNumber implements AggregationExpression { + + @Override + public Document toDocument(AggregationOperationContext context) { + return new Document("$documentNumber", new Document()); + } + } } diff --git a/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/spel/MethodReferenceNode.java b/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/spel/MethodReferenceNode.java index 763ae830e..a184c49be 100644 --- a/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/spel/MethodReferenceNode.java +++ b/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/spel/MethodReferenceNode.java @@ -71,6 +71,7 @@ public class MethodReferenceNode extends ExpressionNode { // DOCUMENT OPERATORS map.put("rank", emptyRef().forOperator("$rank")); map.put("denseRank", emptyRef().forOperator("$denseRank")); + map.put("documentNumber", emptyRef().forOperator("$documentNumber")); // ARITHMETIC OPERATORS map.put("abs", singleArgRef().forOperator("$abs")); diff --git a/spring-data-mongodb/src/test/java/org/springframework/data/mongodb/core/aggregation/DocumentOperatorsUnitTests.java b/spring-data-mongodb/src/test/java/org/springframework/data/mongodb/core/aggregation/DocumentOperatorsUnitTests.java index 27ac1becc..c6604bc54 100644 --- a/spring-data-mongodb/src/test/java/org/springframework/data/mongodb/core/aggregation/DocumentOperatorsUnitTests.java +++ b/spring-data-mongodb/src/test/java/org/springframework/data/mongodb/core/aggregation/DocumentOperatorsUnitTests.java @@ -36,4 +36,9 @@ class DocumentOperatorsUnitTests { assertThat(denseRank().toDocument(Aggregation.DEFAULT_CONTEXT)) .isEqualTo(new Document("$denseRank", new Document())); } + + @Test // GH-3717 + void rendersDocumentNumber() { + assertThat(documentNumber().toDocument(Aggregation.DEFAULT_CONTEXT)).isEqualTo(new Document("$documentNumber", new Document())); + } } diff --git a/spring-data-mongodb/src/test/java/org/springframework/data/mongodb/core/aggregation/SpelExpressionTransformerUnitTests.java b/spring-data-mongodb/src/test/java/org/springframework/data/mongodb/core/aggregation/SpelExpressionTransformerUnitTests.java index 06659820d..3c20b58d5 100644 --- a/spring-data-mongodb/src/test/java/org/springframework/data/mongodb/core/aggregation/SpelExpressionTransformerUnitTests.java +++ b/spring-data-mongodb/src/test/java/org/springframework/data/mongodb/core/aggregation/SpelExpressionTransformerUnitTests.java @@ -966,6 +966,11 @@ public class SpelExpressionTransformerUnitTests { assertThat(transform("denseRank()")).isEqualTo(Document.parse("{ $denseRank : {} }")); } + @Test // GH-3717 + void shouldRenderDocumentNumber() { + assertThat(transform("documentNumber()")).isEqualTo(Document.parse("{ $documentNumber : {} }")); + } + private Object transform(String expression, Object... params) { Object result = transformer.transform(expression, Aggregation.DEFAULT_CONTEXT, params); return result == null ? null : (!(result instanceof org.bson.Document) ? result.toString() : result);