Support expressions in query field projections.
// explicit via dedicated AggregationExpression
query.fields()
.project(StringOperators.valueOf("name").toUpper())
.as("name");
// with a user provided expression parsed from a String
query.fields().project(MongoExpression.create("'$toUpper' : '$name'"))
.as("name")
// using SpEL support
query.fields().project(AggregationSpELExpression.expressionOf("toUpper(name)"))
.as("name");
// with parameter binding
query.fields().project(
MongoExpression.create("'$toUpper' : '?0'").bind("$name")
).as("name")
// via the @Query annotation on repositories
@Query(value = "{ 'id' : ?0 }", fields = "{ 'name': { '$toUpper': '$name' } }")
Closes: #3583
Original pull request: #3585.
This commit is contained in:
committed by
Mark Paluch
parent
191993caef
commit
af6d1eff0c
@@ -1247,6 +1247,69 @@ The `Query` class has some additional methods that provide options for the query
|
||||
* `Query` *skip* `(int skip)` used to skip the provided number of documents in the results (used for paging)
|
||||
* `Query` *with* `(Sort sort)` used to provide sort definition for the results
|
||||
|
||||
[[mongo-template.querying.field-selection]]
|
||||
==== 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.
|
||||
|
||||
.Selecting result fields
|
||||
====
|
||||
[source,java]
|
||||
----
|
||||
public class Person {
|
||||
|
||||
@Id String id;
|
||||
String firstname;
|
||||
|
||||
@Field("last_name")
|
||||
String lastname;
|
||||
|
||||
Address address;
|
||||
}
|
||||
|
||||
query.fields().include("lastname"); <1>
|
||||
|
||||
query.fields().exclude("id").include("lastname") <2>
|
||||
|
||||
query.fields().include("address") <3>
|
||||
|
||||
query.fields().include("address.city") <4>
|
||||
|
||||
|
||||
----
|
||||
<1> Result will contain both `_id` and `last_name` via `{ "last_name" : 1 }`.
|
||||
<2> Result will only contain the `last_name` via `{ "_id" : 0, "last_name" : 1 }`.
|
||||
<3> Result will contain the `_id` and entire `address` object via `{ "address" : 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.
|
||||
|
||||
.Computing result fields with expressions
|
||||
====
|
||||
[source,java]
|
||||
----
|
||||
query.fields()
|
||||
.project(MongoExpression.create("'$toUpper' : '$last_name'")) <1>
|
||||
.as("last_name"); <2>
|
||||
|
||||
query.fields()
|
||||
.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.
|
||||
<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 <<mongodb.repositories.queries.json-based>>.
|
||||
|
||||
[[mongo-template.querying]]
|
||||
=== Methods for Querying for Documents
|
||||
|
||||
|
||||
Reference in New Issue
Block a user