Skip to content

Commit f455640

Browse files
committed
Polishing.
Reorder methods. Tweak Javadoc and documentation wording. Mention projection expressions in the what's new section. Reformat code. See #3583 Original pull request: #3585.
1 parent af6d1ef commit f455640

File tree

7 files changed

+61
-57
lines changed

7 files changed

+61
-57
lines changed

spring-data-mongodb/src/main/java/org/springframework/data/mongodb/BindableMongoExpression.java

+19-18
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,8 @@
1515
*/
1616
package org.springframework.data.mongodb;
1717

18+
import java.util.Arrays;
19+
1820
import org.bson.Document;
1921
import org.bson.codecs.DocumentCodec;
2022
import org.bson.codecs.configuration.CodecRegistry;
@@ -30,15 +32,15 @@
3032
* binding of placeholders like {@code ?0} is delayed upon first call on the the target {@link Document} via
3133
* {@link #toDocument()}.
3234
* <p />
33-
*
35+
*
3436
* <pre class="code">
3537
* $toUpper : $name -> { '$toUpper' : '$name' }
36-
*
38+
*
3739
* { '$toUpper' : '$name' } -> { '$toUpper' : '$name' }
38-
*
40+
*
3941
* { '$toUpper' : '?0' }, "$name" -> { '$toUpper' : '$name' }
4042
* </pre>
41-
*
43+
*
4244
* Some types might require a special {@link org.bson.codecs.Codec}. If so, make sure to provide a {@link CodecRegistry}
4345
* containing the required {@link org.bson.codecs.Codec codec} via {@link #withCodecRegistry(CodecRegistry)}.
4446
*
@@ -49,11 +51,9 @@ public class BindableMongoExpression implements MongoExpression {
4951

5052
private final String expressionString;
5153

52-
@Nullable //
53-
private final CodecRegistryProvider codecRegistryProvider;
54+
private final @Nullable CodecRegistryProvider codecRegistryProvider;
5455

55-
@Nullable //
56-
private final Object[] args;
56+
private final @Nullable Object[] args;
5757

5858
private final Lazy<Document> target;
5959

@@ -118,16 +118,8 @@ public Document toDocument() {
118118
*/
119119
@Override
120120
public String toString() {
121-
return "BindableMongoExpression{" + "expressionString='" + expressionString + '\'' + ", args=" + args + '}';
122-
}
123-
124-
private String wrapJsonIfNecessary(String json) {
125-
126-
if (StringUtils.hasText(json) && (json.startsWith("{") && json.endsWith("}"))) {
127-
return json;
128-
}
129-
130-
return "{" + json + "}";
121+
return "BindableMongoExpression{" + "expressionString='" + expressionString + '\'' + ", args="
122+
+ Arrays.toString(args) + '}';
131123
}
132124

133125
private Document parse() {
@@ -148,4 +140,13 @@ private Document parse() {
148140
: new ParameterBindingDocumentCodec(codecRegistryProvider.getCodecRegistry());
149141
return codec.decode(expression, args);
150142
}
143+
144+
private static String wrapJsonIfNecessary(String json) {
145+
146+
if (StringUtils.hasText(json) && (json.startsWith("{") && json.endsWith("}"))) {
147+
return json;
148+
}
149+
150+
return "{" + json + "}";
151+
}
151152
}

spring-data-mongodb/src/main/java/org/springframework/data/mongodb/MongoExpression.java

+7-7
Original file line numberDiff line numberDiff line change
@@ -39,13 +39,6 @@
3939
@FunctionalInterface
4040
public interface MongoExpression {
4141

42-
/**
43-
* Obtain the native {@link org.bson.Document} representation.
44-
*
45-
* @return never {@literal null}.
46-
*/
47-
org.bson.Document toDocument();
48-
4942
/**
5043
* Create a new {@link MongoExpression} from plain {@link String} (eg. {@code $toUpper : $name}). <br />
5144
* The given expression will be wrapped with <code>{ ... }</code> to match an actual MongoDB {@link org.bson.Document}
@@ -70,4 +63,11 @@ static MongoExpression create(String expression) {
7063
static MongoExpression create(String expression, Object... args) {
7164
return new BindableMongoExpression(expression, args);
7265
}
66+
67+
/**
68+
* Obtain the native {@link org.bson.Document} representation.
69+
*
70+
* @return never {@literal null}.
71+
*/
72+
org.bson.Document toDocument();
7373
}

spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/aggregation/AggregationExpression.java

+12-12
Original file line numberDiff line numberDiff line change
@@ -28,18 +28,6 @@
2828
*/
2929
public interface AggregationExpression extends MongoExpression {
3030

31-
/**
32-
* Obtain the as is (unmapped) representation of the {@link AggregationExpression}. Use
33-
* {@link #toDocument(AggregationOperationContext)} with a matching {@link AggregationOperationContext context} to
34-
* engage domain type mapping including field name resolution.
35-
*
36-
* @see org.springframework.data.mongodb.MongoExpression#toDocument()
37-
*/
38-
@Override
39-
default Document toDocument() {
40-
return toDocument(Aggregation.DEFAULT_CONTEXT);
41-
}
42-
4331
/**
4432
* Create an {@link AggregationExpression} out of a given {@link MongoExpression} to ensure the resulting
4533
* {@link MongoExpression#toDocument() Document} is mapped against the {@link AggregationOperationContext}. <br />
@@ -58,6 +46,18 @@ static AggregationExpression from(MongoExpression expression) {
5846
return (context) -> context.getMappedObject(expression.toDocument());
5947
}
6048

49+
/**
50+
* Obtain the as is (unmapped) representation of the {@link AggregationExpression}. Use
51+
* {@link #toDocument(AggregationOperationContext)} with a matching {@link AggregationOperationContext context} to
52+
* engage domain type mapping including field name resolution.
53+
*
54+
* @see org.springframework.data.mongodb.MongoExpression#toDocument()
55+
*/
56+
@Override
57+
default Document toDocument() {
58+
return toDocument(Aggregation.DEFAULT_CONTEXT);
59+
}
60+
6161
/**
6262
* Turns the {@link AggregationExpression} into a {@link Document} within the given
6363
* {@link AggregationOperationContext}.

spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/query/Field.java

+8-8
Original file line numberDiff line numberDiff line change
@@ -63,21 +63,21 @@ public Field include(String field) {
6363
* result.
6464
*
6565
* <pre class="code">
66-
*
66+
*
6767
* // { 'name' : { '$toUpper' : '$name' } }
68-
*
68+
*
6969
* // native MongoDB expression
7070
* .project(MongoExpression.expressionFromString("'$toUpper' : '$name'")).as("name");
71-
*
71+
*
7272
* // Aggregation Framework expression
7373
* .project(StringOperators.valueOf("name").toUpper()).as("name");
74-
*
74+
*
7575
* // Aggregation Framework SpEL expression
7676
* .project(AggregationSpELExpression.expressionOf("toUpper(name)")).as("name");
7777
* </pre>
7878
*
7979
* @param expression must not be {@literal null}.
80-
* @return new instance of {@link FieldProjectionExpression} - you still need to define the target field name via
80+
* @return new instance of {@link FieldProjectionExpression}. Define the target field name through
8181
* {@link FieldProjectionExpression#as(String) as(String)}.
8282
* @since 3.2
8383
*/
@@ -277,15 +277,15 @@ public int hashCode() {
277277

278278
/**
279279
* Intermediate builder part for projecting a {@link MongoExpression} to a result field.
280-
*
280+
*
281281
* @since 3.2
282282
* @author Christoph Strobl
283283
*/
284284
public interface FieldProjectionExpression {
285285

286286
/**
287-
* Set the name to be used in the result.
288-
*
287+
* Set the name to be used in the result and return a {@link Field}.
288+
*
289289
* @param name must not be {@literal null}.
290290
* @return the calling instance {@link Field}.
291291
*/

spring-data-mongodb/src/test/java/org/springframework/data/mongodb/core/MongoTemplateFieldProjectionTests.java

+2
Original file line numberDiff line numberDiff line change
@@ -39,6 +39,8 @@
3939
import org.springframework.data.mongodb.test.util.Template;
4040

4141
/**
42+
* Integration tests for {@link org.springframework.data.mongodb.core.query.Field}.
43+
*
4244
* @author Christoph Strobl
4345
*/
4446
@ExtendWith(MongoTemplateExtension.class)

src/main/asciidoc/new-features.adoc

+1
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@
55
== What's New in Spring Data MongoDB 3.2
66

77
* Support for <<embedded-entities,Embedded Types>> to unwrap nested objects into the parent `Document`.
8+
* <<mongo-template.querying.field-selection,Support expressions to define field projections>>.
89

910
[[new-features.3.1]]
1011
== What's New in Spring Data MongoDB 3.1

src/main/asciidoc/reference/mongodb.adoc

+12-12
Original file line numberDiff line numberDiff line change
@@ -1251,7 +1251,7 @@ The `Query` class has some additional methods that provide options for the query
12511251
==== Selecting fields
12521252

12531253
MongoDB supports https://docs.mongodb.com/manual/tutorial/project-fields-from-query-results/[projecting fields] returned by a query.
1254-
A projection can in- & exclude fields (the `_id` field is always included unless explicitly excluded) based on their name.
1254+
A projection can include and exclude fields (the `_id` field is always included unless explicitly excluded) based on their name.
12551255

12561256
.Selecting result fields
12571257
====
@@ -1268,13 +1268,13 @@ public class Person {
12681268
Address address;
12691269
}
12701270
1271-
query.fields().include("lastname"); <1>
1271+
query.fields().include("lastname"); <1>
12721272
12731273
query.fields().exclude("id").include("lastname") <2>
12741274
1275-
query.fields().include("address") <3>
1275+
query.fields().include("address") <3>
12761276
1277-
query.fields().include("address.city") <4>
1277+
query.fields().include("address.city") <4>
12781278
12791279
12801280
----
@@ -1284,31 +1284,31 @@ query.fields().include("address.city") <4>
12841284
<4> Result will contain the `_id` and and `address` object that only contains the `city` field via `{ "address.city" : 1 }`.
12851285
====
12861286

1287-
Starting with MongoDB 4.4 it is possible to use the aggregation expressions syntax for field projections as shown below.
1287+
Starting with MongoDB 4.4 you can use aggregation expressions for field projections as shown below:
12881288

1289-
.Computing result fields with expressions
1289+
.Computing result fields using expressions
12901290
====
12911291
[source,java]
12921292
----
12931293
query.fields()
1294-
.project(MongoExpression.create("'$toUpper' : '$last_name'")) <1>
1295-
.as("last_name"); <2>
1294+
.project(MongoExpression.create("'$toUpper' : '$last_name'")) <1>
1295+
.as("last_name"); <2>
12961296
12971297
query.fields()
1298-
.project(StringOperators.valueOf("lastname").toUpper()) <3>
1298+
.project(StringOperators.valueOf("lastname").toUpper()) <3>
12991299
.as("last_name");
13001300
13011301
query.fields()
13021302
.project(AggregationSpELExpression.expressionOf("toUpper(lastname)")) <4>
13031303
.as("last_name");
13041304
----
1305-
<1> Use a native expression. The used field names must refer to the ones of the document within the database.
1306-
<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.
1305+
<1> Use a native expression. The used field name must refer to field names within the database document.
1306+
<2> Assign the field name to which the expression result is projected. The resulting field name is not mapped against the domain model.
13071307
<3> Use an `AggregationExpression`. Other than native `MongoExpression`, field names are mapped to the ones used in the domain model.
13081308
<4> Use SpEL along with an `AggregationExpression` to invoke expression functions. Field names are mapped to the ones used in the domain model.
13091309
====
13101310

1311-
`@Query(fields='...')` allows usage of expression field projections at `Repository` level as described in <<mongodb.repositories.queries.json-based>>.
1311+
`@Query(fields="…")` allows usage of expression field projections at `Repository` level as described in <<mongodb.repositories.queries.json-based>>.
13121312

13131313
[[mongo-template.querying]]
13141314
=== Methods for Querying for Documents

0 commit comments

Comments
 (0)