Browse Source

Add support for $getField aggregation operator.

See #4139
Original pull request: #4182.
pull/4212/head
Christoph Strobl 3 years ago committed by Mark Paluch
parent
commit
82ce0abe1a
No known key found for this signature in database
GPG Key ID: 4406B84C1661DCD1
  1. 49
      spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/aggregation/ObjectOperators.java
  2. 19
      spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/spel/MethodReferenceNode.java
  3. 7
      spring-data-mongodb/src/test/java/org/springframework/data/mongodb/core/aggregation/ObjectOperatorsUnitTests.java
  4. 5
      spring-data-mongodb/src/test/java/org/springframework/data/mongodb/core/aggregation/SpelExpressionTransformerUnitTests.java

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

@ -17,6 +17,7 @@ package org.springframework.data.mongodb.core.aggregation;
import java.util.Arrays; import java.util.Arrays;
import java.util.Collection; import java.util.Collection;
import java.util.Collections;
import org.bson.Document; import org.bson.Document;
import org.springframework.util.Assert; import org.springframework.util.Assert;
@ -124,6 +125,16 @@ public class ObjectOperators {
public ObjectToArray toArray() { public ObjectToArray toArray() {
return ObjectToArray.toArray(value); return ObjectToArray.toArray(value);
} }
/**
* Creates new {@link GetField aggregation expression} that takes the associated value and obtains the value of the
* field with matching name.
*
* @since 4.0
*/
public GetField getField(String fieldName) {
return GetField.getField(fieldName).from(value);
}
} }
/** /**
@ -283,4 +294,42 @@ public class ObjectOperators {
return "$objectToArray"; return "$objectToArray";
} }
} }
/**
* {@link AggregationExpression} for {@code $getField}.
*
* @author Christoph Strobl
* @since 4.0
*/
public static class GetField extends AbstractAggregationExpression {
protected GetField(Object value) {
super(value);
}
public static GetField getField(String fieldName) {
return new GetField(Collections.singletonMap("field", fieldName));
}
public static GetField getField(Field field) {
return getField(field.getTarget());
}
public GetField from(String fieldRef) {
return from(Fields.field(fieldRef));
}
public GetField from(AggregationExpression expression) {
return from((Object) expression);
}
private GetField from(Object fieldRef) {
return new GetField(append("input", fieldRef));
}
@Override
protected String getMongoMethod() {
return "$getField";
}
}
} }

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

@ -165,8 +165,8 @@ public class MethodReferenceNode extends ExpressionNode {
mapArgRef().forOperator("$dateSubtract").mappingParametersTo("startDate", "unit", "amount", "timezone")); mapArgRef().forOperator("$dateSubtract").mappingParametersTo("startDate", "unit", "amount", "timezone"));
map.put("dateDiff", mapArgRef().forOperator("$dateDiff").mappingParametersTo("startDate", "endDate", "unit", map.put("dateDiff", mapArgRef().forOperator("$dateDiff").mappingParametersTo("startDate", "endDate", "unit",
"timezone", "startOfWeek")); "timezone", "startOfWeek"));
map.put("dateTrunc", map.put("dateTrunc", mapArgRef().forOperator("$dateTrunc").mappingParametersTo("date", "unit", "binSize",
mapArgRef().forOperator("$dateTrunc").mappingParametersTo("date", "unit", "binSize", "startOfWeek", "timezone")); "startOfWeek", "timezone"));
map.put("dayOfYear", singleArgRef().forOperator("$dayOfYear")); map.put("dayOfYear", singleArgRef().forOperator("$dayOfYear"));
map.put("dayOfMonth", singleArgRef().forOperator("$dayOfMonth")); map.put("dayOfMonth", singleArgRef().forOperator("$dayOfMonth"));
map.put("dayOfWeek", singleArgRef().forOperator("$dayOfWeek")); map.put("dayOfWeek", singleArgRef().forOperator("$dayOfWeek"));
@ -209,13 +209,6 @@ public class MethodReferenceNode extends ExpressionNode {
map.put("stdDevSamp", arrayArgRef().forOperator("$stdDevSamp")); map.put("stdDevSamp", arrayArgRef().forOperator("$stdDevSamp"));
map.put("covariancePop", arrayArgRef().forOperator("$covariancePop")); map.put("covariancePop", arrayArgRef().forOperator("$covariancePop"));
map.put("covarianceSamp", arrayArgRef().forOperator("$covarianceSamp")); map.put("covarianceSamp", arrayArgRef().forOperator("$covarianceSamp"));
// TYPE OPERATORS
map.put("type", singleArgRef().forOperator("$type"));
// OBJECT OPERATORS
map.put("objectToArray", singleArgRef().forOperator("$objectToArray"));
map.put("mergeObjects", arrayArgRef().forOperator("$mergeObjects"));
map.put("bottom", mapArgRef().forOperator("$bottom") // map.put("bottom", mapArgRef().forOperator("$bottom") //
.mappingParametersTo("output", "sortBy")); .mappingParametersTo("output", "sortBy"));
map.put("bottomN", mapArgRef().forOperator("$bottomN") // map.put("bottomN", mapArgRef().forOperator("$bottomN") //
@ -233,6 +226,14 @@ public class MethodReferenceNode extends ExpressionNode {
map.put("minN", mapArgRef().forOperator("$minN") // map.put("minN", mapArgRef().forOperator("$minN") //
.mappingParametersTo("n", "input")); .mappingParametersTo("n", "input"));
// TYPE OPERATORS
map.put("type", singleArgRef().forOperator("$type"));
// OBJECT OPERATORS
map.put("objectToArray", singleArgRef().forOperator("$objectToArray"));
map.put("mergeObjects", arrayArgRef().forOperator("$mergeObjects"));
map.put("getField", mapArgRef().forOperator("$getField").mappingParametersTo("field", "input"));
// CONVERT OPERATORS // CONVERT OPERATORS
map.put("convert", mapArgRef().forOperator("$convert") // map.put("convert", mapArgRef().forOperator("$convert") //
.mappingParametersTo("input", "to", "onError", "onNull")); .mappingParametersTo("input", "to", "onError", "onNull"));

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

@ -102,4 +102,11 @@ public class ObjectOperatorsUnitTests {
.isEqualTo(Document.parse("{ $objectToArray : " + EXPRESSION_STRING + " }")); .isEqualTo(Document.parse("{ $objectToArray : " + EXPRESSION_STRING + " }"));
} }
@Test // GH-4139
public void getField() {
assertThat(ObjectOperators.valueOf("batman").getField("robin").toDocument(Aggregation.DEFAULT_CONTEXT))
.isEqualTo(Document.parse("{ $getField : { field : \"robin\", input : \"$batman\" }}"));
}
} }

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

@ -1225,6 +1225,11 @@ public class SpelExpressionTransformerUnitTests {
assertThat(transform("dateTrunc(purchaseDate, \"week\", 2, \"monday\")")).isEqualTo("{ $dateTrunc : { date : \"$purchaseDate\", unit : \"week\", binSize : 2, startOfWeek : \"monday\" }}"); assertThat(transform("dateTrunc(purchaseDate, \"week\", 2, \"monday\")")).isEqualTo("{ $dateTrunc : { date : \"$purchaseDate\", unit : \"week\", binSize : 2, startOfWeek : \"monday\" }}");
} }
@Test // GH-4139
void shouldRenderGetField() {
assertThat(transform("getField(\"score\", source)")).isEqualTo("{ $getField : { field : \"score\", input : \"$source\" }}");
}
private Document transform(String expression, Object... params) { private Document transform(String expression, Object... params) {
return (Document) transformer.transform(expression, Aggregation.DEFAULT_CONTEXT, params); return (Document) transformer.transform(expression, Aggregation.DEFAULT_CONTEXT, params);
} }

Loading…
Cancel
Save