Skip to content

Commit 4fcc09c

Browse files
christophstroblmp911de
authored andcommitted
DATAMONGO-1548 - Add support for MongoDB 3.4 aggregation operators.
We now support the following MongoDB 3.4 aggregation operators: $indexOfBytes, $indexOfCP, $split, $strLenBytes, $strLenCP, $substrCP, $indexOfArray, $range, $reverseArray, $reduce, $zip, $in, $isoDayOfWeek, $isoWeek, $isoWeekYear, $switch and $type. Original pull request: spring-projects#423.
1 parent d297f5a commit 4fcc09c

File tree

8 files changed

+2081
-111
lines changed

8 files changed

+2081
-111
lines changed

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

+1,559-82
Large diffs are not rendered by default.

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

+6
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@
2222
import java.util.List;
2323

2424
import org.springframework.data.mongodb.core.aggregation.ExposedFields.ExposedField;
25+
import org.springframework.data.mongodb.core.aggregation.Fields.AggregationField;
2526
import org.springframework.util.Assert;
2627
import org.springframework.util.CompositeIterator;
2728
import org.springframework.util.ObjectUtils;
@@ -406,6 +407,11 @@ public Object getReferenceValue() {
406407
*/
407408
@Override
408409
public String toString() {
410+
411+
if(getRaw().startsWith("$")) {
412+
return getRaw();
413+
}
414+
409415
return String.format("$%s", getRaw());
410416
}
411417

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

+24-1
Original file line numberDiff line numberDiff line change
@@ -187,20 +187,21 @@ public Iterator<Field> iterator() {
187187
}
188188

189189
/**
190-
*
191190
* @return
192191
* @since 1.10
193192
*/
194193
public List<Field> asList() {
195194
return Collections.unmodifiableList(fields);
196195
}
196+
197197
/**
198198
* Value object to encapsulate a field in an aggregation operation.
199199
*
200200
* @author Oliver Gierke
201201
*/
202202
static class AggregationField implements Field {
203203

204+
private final String raw;
204205
private final String name;
205206
private final String target;
206207

@@ -225,6 +226,7 @@ public AggregationField(String name) {
225226
*/
226227
public AggregationField(String name, String target) {
227228

229+
raw = name;
228230
String nameToSet = cleanUp(name);
229231
String targetToSet = cleanUp(target);
230232

@@ -266,6 +268,11 @@ public String getName() {
266268
* @see org.springframework.data.mongodb.core.aggregation.Field#getAlias()
267269
*/
268270
public String getTarget() {
271+
272+
if (isLocalVar()) {
273+
return this.getRaw();
274+
}
275+
269276
return StringUtils.hasText(this.target) ? this.target : this.name;
270277
}
271278

@@ -278,6 +285,22 @@ public boolean isAliased() {
278285
return !getName().equals(getTarget());
279286
}
280287

288+
/**
289+
* @return {@literal true} in case the field name starts with {@code $$}.
290+
* @since 1.10
291+
*/
292+
public boolean isLocalVar() {
293+
return raw.startsWith("$$") && !raw.startsWith("$$$");
294+
}
295+
296+
/**
297+
* @return
298+
* @since 1.10
299+
*/
300+
public String getRaw() {
301+
return raw;
302+
}
303+
281304
/*
282305
* (non-Javadoc)
283306
* @see java.lang.Object#toString()

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

+4-2
Original file line numberDiff line numberDiff line change
@@ -487,8 +487,10 @@ protected Object convert(AggregationExpressionTransformationContext<MethodRefere
487487
} else if (ObjectUtils.nullSafeEquals(methodReference.getArgumentType(), ArgumentType.MAP)) {
488488

489489
Document dbo = new Document();
490-
for (int i = 0; i < methodReference.getArgumentMap().length; i++) {
491-
dbo.put(methodReference.getArgumentMap()[i], transform(node.getChild(i), context));
490+
491+
int i = 0;
492+
for(ExpressionNode child : node) {
493+
dbo.put(methodReference.getArgumentMap()[i++], transform(child, context));
492494
}
493495
args = dbo;
494496
} else {

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

+18
Original file line numberDiff line numberDiff line change
@@ -90,6 +90,12 @@ public class MethodReferenceNode extends ExpressionNode {
9090
map.put("toLower", singleArgumentAggregationMethodReference().forOperator("$toLower"));
9191
map.put("toUpper", singleArgumentAggregationMethodReference().forOperator("$toUpper"));
9292
map.put("strcasecmp", arrayArgumentAggregationMethodReference().forOperator("$strcasecmp"));
93+
map.put("indexOfBytes", arrayArgumentAggregationMethodReference().forOperator("$indexOfBytes"));
94+
map.put("indexOfCP", arrayArgumentAggregationMethodReference().forOperator("$indexOfCP"));
95+
map.put("split", arrayArgumentAggregationMethodReference().forOperator("$split"));
96+
map.put("strLenBytes", singleArgumentAggregationMethodReference().forOperator("$strLenBytes"));
97+
map.put("strLenCP", singleArgumentAggregationMethodReference().forOperator("$strLenCP"));
98+
map.put("substrCP", arrayArgumentAggregationMethodReference().forOperator("$substrCP"));
9399

94100
// TEXT SEARCH OPERATORS
95101
map.put("meta", singleArgumentAggregationMethodReference().forOperator("$meta"));
@@ -102,6 +108,12 @@ public class MethodReferenceNode extends ExpressionNode {
102108
map.put("isArray", singleArgumentAggregationMethodReference().forOperator("$isArray"));
103109
map.put("size", singleArgumentAggregationMethodReference().forOperator("$size"));
104110
map.put("slice", arrayArgumentAggregationMethodReference().forOperator("$slice"));
111+
map.put("reverseArray", singleArgumentAggregationMethodReference().forOperator("$reverseArray"));
112+
map.put("reduce", mapArgumentAggregationMethodReference().forOperator("$reduce").mappingParametersTo("input",
113+
"initialValue", "in"));
114+
map.put("zip", mapArgumentAggregationMethodReference().forOperator("$zip").mappingParametersTo("inputs",
115+
"useLongestLength", "defaults"));
116+
map.put("in", arrayArgumentAggregationMethodReference().forOperator("$in"));
105117

106118
// VARIABLE OPERATORS
107119
map.put("map", mapArgumentAggregationMethodReference().forOperator("$map") //
@@ -124,6 +136,9 @@ public class MethodReferenceNode extends ExpressionNode {
124136
map.put("millisecond", singleArgumentAggregationMethodReference().forOperator("$millisecond"));
125137
map.put("dateToString", mapArgumentAggregationMethodReference().forOperator("$dateToString") //
126138
.mappingParametersTo("format", "date"));
139+
map.put("isoDayOfWeek", singleArgumentAggregationMethodReference().forOperator("$isoDayOfWeek"));
140+
map.put("isoWeek", singleArgumentAggregationMethodReference().forOperator("$isoWeek"));
141+
map.put("isoWeekYear", singleArgumentAggregationMethodReference().forOperator("$isoWeekYear"));
127142

128143
// CONDITIONAL OPERATORS
129144
map.put("cond", mapArgumentAggregationMethodReference().forOperator("$cond") //
@@ -142,6 +157,9 @@ public class MethodReferenceNode extends ExpressionNode {
142157
map.put("stdDevPop", arrayArgumentAggregationMethodReference().forOperator("$stdDevPop"));
143158
map.put("stdDevSamp", arrayArgumentAggregationMethodReference().forOperator("$stdDevSamp"));
144159

160+
// TYPE OPERATORS
161+
map.put("type", singleArgumentAggregationMethodReference().forOperator("$type"));
162+
145163
FUNCTIONS = Collections.unmodifiableMap(map);
146164
}
147165

0 commit comments

Comments
 (0)