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.
This commit is contained in:
@@ -15,6 +15,8 @@
|
|||||||
*/
|
*/
|
||||||
package org.springframework.data.mongodb;
|
package org.springframework.data.mongodb;
|
||||||
|
|
||||||
|
import java.util.Arrays;
|
||||||
|
|
||||||
import org.bson.Document;
|
import org.bson.Document;
|
||||||
import org.bson.codecs.DocumentCodec;
|
import org.bson.codecs.DocumentCodec;
|
||||||
import org.bson.codecs.configuration.CodecRegistry;
|
import org.bson.codecs.configuration.CodecRegistry;
|
||||||
@@ -49,11 +51,9 @@ public class BindableMongoExpression implements MongoExpression {
|
|||||||
|
|
||||||
private final String expressionString;
|
private final String expressionString;
|
||||||
|
|
||||||
@Nullable //
|
private final @Nullable CodecRegistryProvider codecRegistryProvider;
|
||||||
private final CodecRegistryProvider codecRegistryProvider;
|
|
||||||
|
|
||||||
@Nullable //
|
private final @Nullable Object[] args;
|
||||||
private final Object[] args;
|
|
||||||
|
|
||||||
private final Lazy<Document> target;
|
private final Lazy<Document> target;
|
||||||
|
|
||||||
@@ -118,16 +118,8 @@ public class BindableMongoExpression implements MongoExpression {
|
|||||||
*/
|
*/
|
||||||
@Override
|
@Override
|
||||||
public String toString() {
|
public String toString() {
|
||||||
return "BindableMongoExpression{" + "expressionString='" + expressionString + '\'' + ", args=" + args + '}';
|
return "BindableMongoExpression{" + "expressionString='" + expressionString + '\'' + ", args="
|
||||||
}
|
+ Arrays.toString(args) + '}';
|
||||||
|
|
||||||
private String wrapJsonIfNecessary(String json) {
|
|
||||||
|
|
||||||
if (StringUtils.hasText(json) && (json.startsWith("{") && json.endsWith("}"))) {
|
|
||||||
return json;
|
|
||||||
}
|
|
||||||
|
|
||||||
return "{" + json + "}";
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private Document parse() {
|
private Document parse() {
|
||||||
@@ -148,4 +140,13 @@ public class BindableMongoExpression implements MongoExpression {
|
|||||||
: new ParameterBindingDocumentCodec(codecRegistryProvider.getCodecRegistry());
|
: new ParameterBindingDocumentCodec(codecRegistryProvider.getCodecRegistry());
|
||||||
return codec.decode(expression, args);
|
return codec.decode(expression, args);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private static String wrapJsonIfNecessary(String json) {
|
||||||
|
|
||||||
|
if (StringUtils.hasText(json) && (json.startsWith("{") && json.endsWith("}"))) {
|
||||||
|
return json;
|
||||||
|
}
|
||||||
|
|
||||||
|
return "{" + json + "}";
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -39,13 +39,6 @@ package org.springframework.data.mongodb;
|
|||||||
@FunctionalInterface
|
@FunctionalInterface
|
||||||
public interface MongoExpression {
|
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}). <br />
|
* Create a new {@link MongoExpression} from plain {@link String} (eg. {@code $toUpper : $name}). <br />
|
||||||
* The given expression will be wrapped with <code>{ ... }</code> to match an actual MongoDB {@link org.bson.Document}
|
* The given expression will be wrapped with <code>{ ... }</code> to match an actual MongoDB {@link org.bson.Document}
|
||||||
@@ -70,4 +63,11 @@ public interface MongoExpression {
|
|||||||
static MongoExpression create(String expression, Object... args) {
|
static MongoExpression create(String expression, Object... args) {
|
||||||
return new BindableMongoExpression(expression, args);
|
return new BindableMongoExpression(expression, args);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Obtain the native {@link org.bson.Document} representation.
|
||||||
|
*
|
||||||
|
* @return never {@literal null}.
|
||||||
|
*/
|
||||||
|
org.bson.Document toDocument();
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -28,18 +28,6 @@ import org.springframework.data.mongodb.MongoExpression;
|
|||||||
*/
|
*/
|
||||||
public interface AggregationExpression extends 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
|
* Create an {@link AggregationExpression} out of a given {@link MongoExpression} to ensure the resulting
|
||||||
* {@link MongoExpression#toDocument() Document} is mapped against the {@link AggregationOperationContext}. <br />
|
* {@link MongoExpression#toDocument() Document} is mapped against the {@link AggregationOperationContext}. <br />
|
||||||
@@ -58,6 +46,18 @@ public interface AggregationExpression extends MongoExpression {
|
|||||||
return (context) -> context.getMappedObject(expression.toDocument());
|
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
|
* Turns the {@link AggregationExpression} into a {@link Document} within the given
|
||||||
* {@link AggregationOperationContext}.
|
* {@link AggregationOperationContext}.
|
||||||
|
|||||||
@@ -77,7 +77,7 @@ public class Field {
|
|||||||
* </pre>
|
* </pre>
|
||||||
*
|
*
|
||||||
* @param expression must not be {@literal null}.
|
* @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)}.
|
* {@link FieldProjectionExpression#as(String) as(String)}.
|
||||||
* @since 3.2
|
* @since 3.2
|
||||||
*/
|
*/
|
||||||
@@ -284,7 +284,7 @@ public class Field {
|
|||||||
public interface FieldProjectionExpression {
|
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}.
|
* @param name must not be {@literal null}.
|
||||||
* @return the calling instance {@link Field}.
|
* @return the calling instance {@link Field}.
|
||||||
|
|||||||
@@ -39,6 +39,8 @@ import org.springframework.data.mongodb.test.util.MongoTestTemplate;
|
|||||||
import org.springframework.data.mongodb.test.util.Template;
|
import org.springframework.data.mongodb.test.util.Template;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
* Integration tests for {@link org.springframework.data.mongodb.core.query.Field}.
|
||||||
|
*
|
||||||
* @author Christoph Strobl
|
* @author Christoph Strobl
|
||||||
*/
|
*/
|
||||||
@ExtendWith(MongoTemplateExtension.class)
|
@ExtendWith(MongoTemplateExtension.class)
|
||||||
|
|||||||
@@ -5,6 +5,7 @@
|
|||||||
== What's New in Spring Data MongoDB 3.2
|
== What's New in Spring Data MongoDB 3.2
|
||||||
|
|
||||||
* Support for <<embedded-entities,Embedded Types>> to unwrap nested objects into the parent `Document`.
|
* Support for <<embedded-entities,Embedded Types>> to unwrap nested objects into the parent `Document`.
|
||||||
|
* <<mongo-template.querying.field-selection,Support expressions to define field projections>>.
|
||||||
|
|
||||||
[[new-features.3.1]]
|
[[new-features.3.1]]
|
||||||
== What's New in Spring Data MongoDB 3.1
|
== What's New in Spring Data MongoDB 3.1
|
||||||
|
|||||||
@@ -1251,7 +1251,7 @@ The `Query` class has some additional methods that provide options for the query
|
|||||||
==== Selecting fields
|
==== Selecting fields
|
||||||
|
|
||||||
MongoDB supports https://docs.mongodb.com/manual/tutorial/project-fields-from-query-results/[projecting fields] returned by a query.
|
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
|
.Selecting result fields
|
||||||
====
|
====
|
||||||
@@ -1284,9 +1284,9 @@ 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 }`.
|
<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]
|
[source,java]
|
||||||
----
|
----
|
||||||
@@ -1302,13 +1302,13 @@ query.fields()
|
|||||||
.project(AggregationSpELExpression.expressionOf("toUpper(lastname)")) <4>
|
.project(AggregationSpELExpression.expressionOf("toUpper(lastname)")) <4>
|
||||||
.as("last_name");
|
.as("last_name");
|
||||||
----
|
----
|
||||||
<1> Use a native expression. The used field names must refer to the ones of the document within the database.
|
<1> Use a native expression. The used field name must refer to field names within the database document.
|
||||||
<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.
|
<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.
|
<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.
|
<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 <<mongodb.repositories.queries.json-based>>.
|
`@Query(fields="…")` allows usage of expression field projections at `Repository` level as described in <<mongodb.repositories.queries.json-based>>.
|
||||||
|
|
||||||
[[mongo-template.querying]]
|
[[mongo-template.querying]]
|
||||||
=== Methods for Querying for Documents
|
=== Methods for Querying for Documents
|
||||||
|
|||||||
Reference in New Issue
Block a user