Skip to content

Commit d4a6614

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

File tree

4 files changed

+92
-0
lines changed

4 files changed

+92
-0
lines changed

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

+72
Original file line numberDiff line numberDiff line change
@@ -18,8 +18,10 @@
1818
import java.util.Arrays;
1919
import java.util.Collection;
2020
import java.util.Collections;
21+
import java.util.Set;
2122

2223
import org.bson.Document;
24+
import org.springframework.data.mongodb.core.aggregation.Aggregation.SystemVariable;
2325
import org.springframework.util.Assert;
2426

2527
/**
@@ -135,6 +137,26 @@ public ObjectToArray toArray() {
135137
public GetField getField(String fieldName) {
136138
return GetField.getField(fieldName).from(value);
137139
}
140+
141+
/**
142+
* Creates new {@link SetField aggregation expression} that takes the associated value and obtains the value of the
143+
* field with matching name.
144+
*
145+
* @since 4.0
146+
*/
147+
public SetField setField(String fieldName) {
148+
return SetField.setField(fieldName).of(value);
149+
}
150+
151+
/**
152+
* Creates new {@link SetField aggregation expression} that takes the associated value and obtains the value of the
153+
* field with matching name.
154+
*
155+
* @since 4.0
156+
*/
157+
public AggregationExpression removeField(String fieldName) {
158+
return SetField.setField(fieldName).of(value).toValue(SystemVariable.REMOVE);
159+
}
138160
}
139161

140162
/**
@@ -332,4 +354,54 @@ protected String getMongoMethod() {
332354
return "$getField";
333355
}
334356
}
357+
358+
/**
359+
* {@link AggregationExpression} for {@code $setField}.
360+
*
361+
* @author Christoph Strobl
362+
* @since 4.0
363+
*/
364+
public static class SetField extends AbstractAggregationExpression {
365+
366+
protected SetField(Object value) {
367+
super(value);
368+
}
369+
370+
public static SetField setField(String fieldName) {
371+
return new SetField(Collections.singletonMap("field", fieldName));
372+
}
373+
374+
public static SetField setField(Field field) {
375+
return setField(field.getTarget());
376+
}
377+
378+
public SetField of(String fieldRef) {
379+
return of(Fields.field(fieldRef));
380+
}
381+
382+
public SetField of(AggregationExpression expression) {
383+
return of((Object) expression);
384+
}
385+
386+
private SetField of(Object fieldRef) {
387+
return new SetField(append("input", fieldRef));
388+
}
389+
390+
public SetField toValueOf(String fieldReference) {
391+
return toValue(Fields.field(fieldReference));
392+
}
393+
394+
public SetField toValueOf(AggregationExpression expression) {
395+
return toValue(expression);
396+
}
397+
398+
public SetField toValue(Object value) {
399+
return new SetField(append("value", value));
400+
}
401+
402+
@Override
403+
protected String getMongoMethod() {
404+
return "$setField";
405+
}
406+
}
335407
}

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

+1
Original file line numberDiff line numberDiff line change
@@ -233,6 +233,7 @@ public class MethodReferenceNode extends ExpressionNode {
233233
map.put("objectToArray", singleArgRef().forOperator("$objectToArray"));
234234
map.put("mergeObjects", arrayArgRef().forOperator("$mergeObjects"));
235235
map.put("getField", mapArgRef().forOperator("$getField").mappingParametersTo("field", "input"));
236+
map.put("setField", mapArgRef().forOperator("$setField").mappingParametersTo("field", "value", "input"));
236237

237238
// CONVERT OPERATORS
238239
map.put("convert", mapArgRef().forOperator("$convert") //

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

+14
Original file line numberDiff line numberDiff line change
@@ -109,4 +109,18 @@ public void getField() {
109109
.isEqualTo(Document.parse("{ $getField : { field : \"robin\", input : \"$batman\" }}"));
110110
}
111111

112+
@Test // GH-4139
113+
public void setField() {
114+
115+
assertThat(ObjectOperators.valueOf("batman").setField("friend").toValue("robin").toDocument(Aggregation.DEFAULT_CONTEXT))
116+
.isEqualTo(Document.parse("{ $setField : { field : \"friend\", value : \"robin\", input : \"$batman\" }}"));
117+
}
118+
119+
@Test // GH-4139
120+
public void removeField() {
121+
122+
assertThat(ObjectOperators.valueOf("batman").removeField("joker").toDocument(Aggregation.DEFAULT_CONTEXT))
123+
.isEqualTo(Document.parse("{ $setField : { field : \"joker\", value : \"$$REMOVE\", input : \"$batman\" }}"));
124+
}
125+
112126
}

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

+5
Original file line numberDiff line numberDiff line change
@@ -1230,6 +1230,11 @@ void shouldRenderGetField() {
12301230
assertThat(transform("getField(\"score\", source)")).isEqualTo("{ $getField : { field : \"score\", input : \"$source\" }}");
12311231
}
12321232

1233+
@Test // GH-4139
1234+
void shouldRenderSetField() {
1235+
assertThat(transform("setField(\"score\", 100, source)")).isEqualTo("{ $setField : { field : \"score\", value : 100, input : \"$source\" }}");
1236+
}
1237+
12331238
private Document transform(String expression, Object... params) {
12341239
return (Document) transformer.transform(expression, Aggregation.DEFAULT_CONTEXT, params);
12351240
}

0 commit comments

Comments
 (0)