Skip to content

Commit 82ce0ab

Browse files
christophstroblmp911de
authored andcommitted
Add support for $getField aggregation operator.
See #4139 Original pull request: #4182.
1 parent dec7c12 commit 82ce0ab

File tree

4 files changed

+71
-9
lines changed

4 files changed

+71
-9
lines changed

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

+49
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@
1717

1818
import java.util.Arrays;
1919
import java.util.Collection;
20+
import java.util.Collections;
2021

2122
import org.bson.Document;
2223
import org.springframework.util.Assert;
@@ -124,6 +125,16 @@ public MergeObjects mergeWithValuesOf(AggregationExpression... expression) {
124125
public ObjectToArray toArray() {
125126
return ObjectToArray.toArray(value);
126127
}
128+
129+
/**
130+
* Creates new {@link GetField aggregation expression} that takes the associated value and obtains the value of the
131+
* field with matching name.
132+
*
133+
* @since 4.0
134+
*/
135+
public GetField getField(String fieldName) {
136+
return GetField.getField(fieldName).from(value);
137+
}
127138
}
128139

129140
/**
@@ -283,4 +294,42 @@ protected String getMongoMethod() {
283294
return "$objectToArray";
284295
}
285296
}
297+
298+
/**
299+
* {@link AggregationExpression} for {@code $getField}.
300+
*
301+
* @author Christoph Strobl
302+
* @since 4.0
303+
*/
304+
public static class GetField extends AbstractAggregationExpression {
305+
306+
protected GetField(Object value) {
307+
super(value);
308+
}
309+
310+
public static GetField getField(String fieldName) {
311+
return new GetField(Collections.singletonMap("field", fieldName));
312+
}
313+
314+
public static GetField getField(Field field) {
315+
return getField(field.getTarget());
316+
}
317+
318+
public GetField from(String fieldRef) {
319+
return from(Fields.field(fieldRef));
320+
}
321+
322+
public GetField from(AggregationExpression expression) {
323+
return from((Object) expression);
324+
}
325+
326+
private GetField from(Object fieldRef) {
327+
return new GetField(append("input", fieldRef));
328+
}
329+
330+
@Override
331+
protected String getMongoMethod() {
332+
return "$getField";
333+
}
334+
}
286335
}

spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/spel/MethodReferenceNode.java

+10-9
Original file line numberDiff line numberDiff line change
@@ -165,8 +165,8 @@ public class MethodReferenceNode extends ExpressionNode {
165165
mapArgRef().forOperator("$dateSubtract").mappingParametersTo("startDate", "unit", "amount", "timezone"));
166166
map.put("dateDiff", mapArgRef().forOperator("$dateDiff").mappingParametersTo("startDate", "endDate", "unit",
167167
"timezone", "startOfWeek"));
168-
map.put("dateTrunc",
169-
mapArgRef().forOperator("$dateTrunc").mappingParametersTo("date", "unit", "binSize", "startOfWeek", "timezone"));
168+
map.put("dateTrunc", mapArgRef().forOperator("$dateTrunc").mappingParametersTo("date", "unit", "binSize",
169+
"startOfWeek", "timezone"));
170170
map.put("dayOfYear", singleArgRef().forOperator("$dayOfYear"));
171171
map.put("dayOfMonth", singleArgRef().forOperator("$dayOfMonth"));
172172
map.put("dayOfWeek", singleArgRef().forOperator("$dayOfWeek"));
@@ -209,13 +209,6 @@ public class MethodReferenceNode extends ExpressionNode {
209209
map.put("stdDevSamp", arrayArgRef().forOperator("$stdDevSamp"));
210210
map.put("covariancePop", arrayArgRef().forOperator("$covariancePop"));
211211
map.put("covarianceSamp", arrayArgRef().forOperator("$covarianceSamp"));
212-
213-
// TYPE OPERATORS
214-
map.put("type", singleArgRef().forOperator("$type"));
215-
216-
// OBJECT OPERATORS
217-
map.put("objectToArray", singleArgRef().forOperator("$objectToArray"));
218-
map.put("mergeObjects", arrayArgRef().forOperator("$mergeObjects"));
219212
map.put("bottom", mapArgRef().forOperator("$bottom") //
220213
.mappingParametersTo("output", "sortBy"));
221214
map.put("bottomN", mapArgRef().forOperator("$bottomN") //
@@ -233,6 +226,14 @@ public class MethodReferenceNode extends ExpressionNode {
233226
map.put("minN", mapArgRef().forOperator("$minN") //
234227
.mappingParametersTo("n", "input"));
235228

229+
// TYPE OPERATORS
230+
map.put("type", singleArgRef().forOperator("$type"));
231+
232+
// OBJECT OPERATORS
233+
map.put("objectToArray", singleArgRef().forOperator("$objectToArray"));
234+
map.put("mergeObjects", arrayArgRef().forOperator("$mergeObjects"));
235+
map.put("getField", mapArgRef().forOperator("$getField").mappingParametersTo("field", "input"));
236+
236237
// CONVERT OPERATORS
237238
map.put("convert", mapArgRef().forOperator("$convert") //
238239
.mappingParametersTo("input", "to", "onError", "onNull"));

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

+7
Original file line numberDiff line numberDiff line change
@@ -102,4 +102,11 @@ public void toArrayWithExpression() {
102102
.isEqualTo(Document.parse("{ $objectToArray : " + EXPRESSION_STRING + " }"));
103103
}
104104

105+
@Test // GH-4139
106+
public void getField() {
107+
108+
assertThat(ObjectOperators.valueOf("batman").getField("robin").toDocument(Aggregation.DEFAULT_CONTEXT))
109+
.isEqualTo(Document.parse("{ $getField : { field : \"robin\", input : \"$batman\" }}"));
110+
}
111+
105112
}

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

+5
Original file line numberDiff line numberDiff line change
@@ -1225,6 +1225,11 @@ void shouldRenderDateTrunc() {
12251225
assertThat(transform("dateTrunc(purchaseDate, \"week\", 2, \"monday\")")).isEqualTo("{ $dateTrunc : { date : \"$purchaseDate\", unit : \"week\", binSize : 2, startOfWeek : \"monday\" }}");
12261226
}
12271227

1228+
@Test // GH-4139
1229+
void shouldRenderGetField() {
1230+
assertThat(transform("getField(\"score\", source)")).isEqualTo("{ $getField : { field : \"score\", input : \"$source\" }}");
1231+
}
1232+
12281233
private Document transform(String expression, Object... params) {
12291234
return (Document) transformer.transform(expression, Aggregation.DEFAULT_CONTEXT, params);
12301235
}

0 commit comments

Comments
 (0)