diff --git a/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/BindableMongoExpression.java b/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/BindableMongoExpression.java
index 4ecc52ce5..982f683d5 100644
--- a/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/BindableMongoExpression.java
+++ b/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/BindableMongoExpression.java
@@ -15,6 +15,8 @@
*/
package org.springframework.data.mongodb;
+import java.util.Arrays;
+
import org.bson.Document;
import org.bson.codecs.DocumentCodec;
import org.bson.codecs.configuration.CodecRegistry;
@@ -30,15 +32,15 @@ import org.springframework.util.StringUtils;
* binding of placeholders like {@code ?0} is delayed upon first call on the the target {@link Document} via
* {@link #toDocument()}.
*
- *
+ *
*
* $toUpper : $name -> { '$toUpper' : '$name' }
- *
+ *
* { '$toUpper' : '$name' } -> { '$toUpper' : '$name' }
- *
+ *
* { '$toUpper' : '?0' }, "$name" -> { '$toUpper' : '$name' }
*
- *
+ *
* Some types might require a special {@link org.bson.codecs.Codec}. If so, make sure to provide a {@link CodecRegistry}
* containing the required {@link org.bson.codecs.Codec codec} via {@link #withCodecRegistry(CodecRegistry)}.
*
@@ -49,11 +51,9 @@ public class BindableMongoExpression implements MongoExpression {
private final String expressionString;
- @Nullable //
- private final CodecRegistryProvider codecRegistryProvider;
+ private final @Nullable CodecRegistryProvider codecRegistryProvider;
- @Nullable //
- private final Object[] args;
+ private final @Nullable Object[] args;
private final Lazy target;
@@ -118,16 +118,8 @@ public class BindableMongoExpression implements MongoExpression {
*/
@Override
public String toString() {
- return "BindableMongoExpression{" + "expressionString='" + expressionString + '\'' + ", args=" + args + '}';
- }
-
- private String wrapJsonIfNecessary(String json) {
-
- if (StringUtils.hasText(json) && (json.startsWith("{") && json.endsWith("}"))) {
- return json;
- }
-
- return "{" + json + "}";
+ return "BindableMongoExpression{" + "expressionString='" + expressionString + '\'' + ", args="
+ + Arrays.toString(args) + '}';
}
private Document parse() {
@@ -148,4 +140,13 @@ public class BindableMongoExpression implements MongoExpression {
: new ParameterBindingDocumentCodec(codecRegistryProvider.getCodecRegistry());
return codec.decode(expression, args);
}
+
+ private static String wrapJsonIfNecessary(String json) {
+
+ if (StringUtils.hasText(json) && (json.startsWith("{") && json.endsWith("}"))) {
+ return json;
+ }
+
+ return "{" + json + "}";
+ }
}
diff --git a/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/MongoExpression.java b/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/MongoExpression.java
index c69fd97f4..541118b11 100644
--- a/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/MongoExpression.java
+++ b/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/MongoExpression.java
@@ -39,13 +39,6 @@ package org.springframework.data.mongodb;
@FunctionalInterface
public interface MongoExpression {
- /**
- * Obtain the native {@link org.bson.Document} representation.
- *
- * @return never {@literal null}.
- */
- org.bson.Document toDocument();
-
/**
* Create a new {@link MongoExpression} from plain {@link String} (eg. {@code $toUpper : $name}).
* The given expression will be wrapped with { ... } to match an actual MongoDB {@link org.bson.Document}
@@ -70,4 +63,11 @@ public interface MongoExpression {
static MongoExpression create(String expression, Object... args) {
return new BindableMongoExpression(expression, args);
}
+
+ /**
+ * Obtain the native {@link org.bson.Document} representation.
+ *
+ * @return never {@literal null}.
+ */
+ org.bson.Document toDocument();
}
diff --git a/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/aggregation/AggregationExpression.java b/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/aggregation/AggregationExpression.java
index 879751b29..b2fee4439 100644
--- a/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/aggregation/AggregationExpression.java
+++ b/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/aggregation/AggregationExpression.java
@@ -28,18 +28,6 @@ import org.springframework.data.mongodb.MongoExpression;
*/
public interface AggregationExpression extends MongoExpression {
- /**
- * Obtain the as is (unmapped) representation of the {@link AggregationExpression}. Use
- * {@link #toDocument(AggregationOperationContext)} with a matching {@link AggregationOperationContext context} to
- * engage domain type mapping including field name resolution.
- *
- * @see org.springframework.data.mongodb.MongoExpression#toDocument()
- */
- @Override
- default Document toDocument() {
- return toDocument(Aggregation.DEFAULT_CONTEXT);
- }
-
/**
* Create an {@link AggregationExpression} out of a given {@link MongoExpression} to ensure the resulting
* {@link MongoExpression#toDocument() Document} is mapped against the {@link AggregationOperationContext}.
@@ -58,6 +46,18 @@ public interface AggregationExpression extends MongoExpression {
return (context) -> context.getMappedObject(expression.toDocument());
}
+ /**
+ * Obtain the as is (unmapped) representation of the {@link AggregationExpression}. Use
+ * {@link #toDocument(AggregationOperationContext)} with a matching {@link AggregationOperationContext context} to
+ * engage domain type mapping including field name resolution.
+ *
+ * @see org.springframework.data.mongodb.MongoExpression#toDocument()
+ */
+ @Override
+ default Document toDocument() {
+ return toDocument(Aggregation.DEFAULT_CONTEXT);
+ }
+
/**
* Turns the {@link AggregationExpression} into a {@link Document} within the given
* {@link AggregationOperationContext}.
diff --git a/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/query/Field.java b/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/query/Field.java
index 711e5d81d..0561bbdca 100644
--- a/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/query/Field.java
+++ b/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/query/Field.java
@@ -63,21 +63,21 @@ public class Field {
* result.
*
*
- *
+ *
* // { 'name' : { '$toUpper' : '$name' } }
- *
+ *
* // native MongoDB expression
* .project(MongoExpression.expressionFromString("'$toUpper' : '$name'")).as("name");
- *
+ *
* // Aggregation Framework expression
* .project(StringOperators.valueOf("name").toUpper()).as("name");
- *
+ *
* // Aggregation Framework SpEL expression
* .project(AggregationSpELExpression.expressionOf("toUpper(name)")).as("name");
*
*
* @param expression must not be {@literal null}.
- * @return new instance of {@link FieldProjectionExpression} - you still need to define the target field name via
+ * @return new instance of {@link FieldProjectionExpression}. Define the target field name through
* {@link FieldProjectionExpression#as(String) as(String)}.
* @since 3.2
*/
@@ -277,15 +277,15 @@ public class Field {
/**
* Intermediate builder part for projecting a {@link MongoExpression} to a result field.
- *
+ *
* @since 3.2
* @author Christoph Strobl
*/
public interface FieldProjectionExpression {
/**
- * Set the name to be used in the result.
- *
+ * Set the name to be used in the result and return a {@link Field}.
+ *
* @param name must not be {@literal null}.
* @return the calling instance {@link Field}.
*/
diff --git a/spring-data-mongodb/src/test/java/org/springframework/data/mongodb/core/MongoTemplateFieldProjectionTests.java b/spring-data-mongodb/src/test/java/org/springframework/data/mongodb/core/MongoTemplateFieldProjectionTests.java
index d97e0afdc..144e30c4f 100644
--- a/spring-data-mongodb/src/test/java/org/springframework/data/mongodb/core/MongoTemplateFieldProjectionTests.java
+++ b/spring-data-mongodb/src/test/java/org/springframework/data/mongodb/core/MongoTemplateFieldProjectionTests.java
@@ -39,6 +39,8 @@ import org.springframework.data.mongodb.test.util.MongoTestTemplate;
import org.springframework.data.mongodb.test.util.Template;
/**
+ * Integration tests for {@link org.springframework.data.mongodb.core.query.Field}.
+ *
* @author Christoph Strobl
*/
@ExtendWith(MongoTemplateExtension.class)
diff --git a/src/main/asciidoc/new-features.adoc b/src/main/asciidoc/new-features.adoc
index 9cf28cb30..829fee072 100644
--- a/src/main/asciidoc/new-features.adoc
+++ b/src/main/asciidoc/new-features.adoc
@@ -5,6 +5,7 @@
== What's New in Spring Data MongoDB 3.2
* Support for <> to unwrap nested objects into the parent `Document`.
+* <>.
[[new-features.3.1]]
== What's New in Spring Data MongoDB 3.1
diff --git a/src/main/asciidoc/reference/mongodb.adoc b/src/main/asciidoc/reference/mongodb.adoc
index 604dd88b8..a463689bd 100644
--- a/src/main/asciidoc/reference/mongodb.adoc
+++ b/src/main/asciidoc/reference/mongodb.adoc
@@ -1251,7 +1251,7 @@ The `Query` class has some additional methods that provide options for the query
==== Selecting fields
MongoDB supports https://docs.mongodb.com/manual/tutorial/project-fields-from-query-results/[projecting fields] returned by a query.
-A projection can in- & exclude fields (the `_id` field is always included unless explicitly excluded) based on their name.
+A projection can include and exclude fields (the `_id` field is always included unless explicitly excluded) based on their name.
.Selecting result fields
====
@@ -1268,13 +1268,13 @@ public class Person {
Address address;
}
-query.fields().include("lastname"); <1>
+query.fields().include("lastname"); <1>
query.fields().exclude("id").include("lastname") <2>
-query.fields().include("address") <3>
+query.fields().include("address") <3>
-query.fields().include("address.city") <4>
+query.fields().include("address.city") <4>
----
@@ -1284,31 +1284,31 @@ query.fields().include("address.city") <4>
<4> Result will contain the `_id` and and `address` object that only contains the `city` field via `{ "address.city" : 1 }`.
====
-Starting with MongoDB 4.4 it is possible to use the aggregation expressions syntax for field projections as shown below.
+Starting with MongoDB 4.4 you can use aggregation expressions for field projections as shown below:
-.Computing result fields with expressions
+.Computing result fields using expressions
====
[source,java]
----
query.fields()
- .project(MongoExpression.create("'$toUpper' : '$last_name'")) <1>
- .as("last_name"); <2>
+ .project(MongoExpression.create("'$toUpper' : '$last_name'")) <1>
+ .as("last_name"); <2>
query.fields()
- .project(StringOperators.valueOf("lastname").toUpper()) <3>
+ .project(StringOperators.valueOf("lastname").toUpper()) <3>
.as("last_name");
query.fields()
.project(AggregationSpELExpression.expressionOf("toUpper(lastname)")) <4>
.as("last_name");
----
-<1> Use a native expression. The used field names must refer to the ones of the document within the database.
-<2> Assign the field name that shall hold the expression result in the target document. The resulting field name will never be mapped against the domain model.
+<1> Use a native expression. The used field name must refer to field names within the database document.
+<2> Assign the field name to which the expression result is projected. The resulting field name is not mapped against the domain model.
<3> Use an `AggregationExpression`. Other than native `MongoExpression`, field names are mapped to the ones used in the domain model.
<4> Use SpEL along with an `AggregationExpression` to invoke expression functions. Field names are mapped to the ones used in the domain model.
====
-`@Query(fields='...')` allows usage of expression field projections at `Repository` level as described in <>.
+`@Query(fields="…")` allows usage of expression field projections at `Repository` level as described in <>.
[[mongo-template.querying]]
=== Methods for Querying for Documents