Add support for $setField aggregation operator.

See #4139
Original pull request: #4182.
This commit is contained in:
Christoph Strobl
2022-09-23 14:09:41 +02:00
committed by Mark Paluch
parent 82ce0abe1a
commit d4a6614c11
4 changed files with 92 additions and 0 deletions

View File

@@ -18,8 +18,10 @@ package org.springframework.data.mongodb.core.aggregation;
import java.util.Arrays;
import java.util.Collection;
import java.util.Collections;
import java.util.Set;
import org.bson.Document;
import org.springframework.data.mongodb.core.aggregation.Aggregation.SystemVariable;
import org.springframework.util.Assert;
/**
@@ -135,6 +137,26 @@ public class ObjectOperators {
public GetField getField(String fieldName) {
return GetField.getField(fieldName).from(value);
}
/**
* Creates new {@link SetField aggregation expression} that takes the associated value and obtains the value of the
* field with matching name.
*
* @since 4.0
*/
public SetField setField(String fieldName) {
return SetField.setField(fieldName).of(value);
}
/**
* Creates new {@link SetField aggregation expression} that takes the associated value and obtains the value of the
* field with matching name.
*
* @since 4.0
*/
public AggregationExpression removeField(String fieldName) {
return SetField.setField(fieldName).of(value).toValue(SystemVariable.REMOVE);
}
}
/**
@@ -332,4 +354,54 @@ public class ObjectOperators {
return "$getField";
}
}
/**
* {@link AggregationExpression} for {@code $setField}.
*
* @author Christoph Strobl
* @since 4.0
*/
public static class SetField extends AbstractAggregationExpression {
protected SetField(Object value) {
super(value);
}
public static SetField setField(String fieldName) {
return new SetField(Collections.singletonMap("field", fieldName));
}
public static SetField setField(Field field) {
return setField(field.getTarget());
}
public SetField of(String fieldRef) {
return of(Fields.field(fieldRef));
}
public SetField of(AggregationExpression expression) {
return of((Object) expression);
}
private SetField of(Object fieldRef) {
return new SetField(append("input", fieldRef));
}
public SetField toValueOf(String fieldReference) {
return toValue(Fields.field(fieldReference));
}
public SetField toValueOf(AggregationExpression expression) {
return toValue(expression);
}
public SetField toValue(Object value) {
return new SetField(append("value", value));
}
@Override
protected String getMongoMethod() {
return "$setField";
}
}
}

View File

@@ -233,6 +233,7 @@ public class MethodReferenceNode extends ExpressionNode {
map.put("objectToArray", singleArgRef().forOperator("$objectToArray"));
map.put("mergeObjects", arrayArgRef().forOperator("$mergeObjects"));
map.put("getField", mapArgRef().forOperator("$getField").mappingParametersTo("field", "input"));
map.put("setField", mapArgRef().forOperator("$setField").mappingParametersTo("field", "value", "input"));
// CONVERT OPERATORS
map.put("convert", mapArgRef().forOperator("$convert") //

View File

@@ -109,4 +109,18 @@ public class ObjectOperatorsUnitTests {
.isEqualTo(Document.parse("{ $getField : { field : \"robin\", input : \"$batman\" }}"));
}
@Test // GH-4139
public void setField() {
assertThat(ObjectOperators.valueOf("batman").setField("friend").toValue("robin").toDocument(Aggregation.DEFAULT_CONTEXT))
.isEqualTo(Document.parse("{ $setField : { field : \"friend\", value : \"robin\", input : \"$batman\" }}"));
}
@Test // GH-4139
public void removeField() {
assertThat(ObjectOperators.valueOf("batman").removeField("joker").toDocument(Aggregation.DEFAULT_CONTEXT))
.isEqualTo(Document.parse("{ $setField : { field : \"joker\", value : \"$$REMOVE\", input : \"$batman\" }}"));
}
}

View File

@@ -1230,6 +1230,11 @@ public class SpelExpressionTransformerUnitTests {
assertThat(transform("getField(\"score\", source)")).isEqualTo("{ $getField : { field : \"score\", input : \"$source\" }}");
}
@Test // GH-4139
void shouldRenderSetField() {
assertThat(transform("setField(\"score\", 100, source)")).isEqualTo("{ $setField : { field : \"score\", value : 100, input : \"$source\" }}");
}
private Document transform(String expression, Object... params) {
return (Document) transformer.transform(expression, Aggregation.DEFAULT_CONTEXT, params);
}