DATAMONGO-2077 - Enhance SpEL aggregation support.
Added aggregation method detection for: - trim, ltrim, trim - arrayToObject, objectToArray, indexOfArray - dateFromString, dateFromParts, isoDateFromParts, dateToParts - mergeObjects - convert, toBool, toDate, toDecimal, toDouble, toInt, toLong, toObjectId, toString - range Original pull request: #639.
This commit is contained in:
committed by
Mark Paluch
parent
9cc7fc2a08
commit
3811ddf912
@@ -98,6 +98,11 @@ public class MethodReferenceNode extends ExpressionNode {
|
||||
map.put("strLenBytes", singleArgumentAggregationMethodReference().forOperator("$strLenBytes"));
|
||||
map.put("strLenCP", singleArgumentAggregationMethodReference().forOperator("$strLenCP"));
|
||||
map.put("substrCP", arrayArgumentAggregationMethodReference().forOperator("$substrCP"));
|
||||
map.put("trim", mapArgumentAggregationMethodReference().forOperator("$trim").mappingParametersTo("input", "chars"));
|
||||
map.put("ltrim",
|
||||
mapArgumentAggregationMethodReference().forOperator("$ltrim").mappingParametersTo("input", "chars"));
|
||||
map.put("rtrim",
|
||||
mapArgumentAggregationMethodReference().forOperator("$rtrim").mappingParametersTo("input", "chars"));
|
||||
|
||||
// TEXT SEARCH OPERATORS
|
||||
map.put("meta", singleArgumentAggregationMethodReference().forOperator("$meta"));
|
||||
@@ -116,6 +121,9 @@ public class MethodReferenceNode extends ExpressionNode {
|
||||
map.put("zip", mapArgumentAggregationMethodReference().forOperator("$zip").mappingParametersTo("inputs",
|
||||
"useLongestLength", "defaults"));
|
||||
map.put("in", arrayArgumentAggregationMethodReference().forOperator("$in"));
|
||||
map.put("arrayToObject", singleArgumentAggregationMethodReference().forOperator("$arrayToObject"));
|
||||
map.put("indexOfArray", arrayArgumentAggregationMethodReference().forOperator("$indexOfArray"));
|
||||
map.put("range", arrayArgumentAggregationMethodReference().forOperator("$range"));
|
||||
|
||||
// VARIABLE OPERATORS
|
||||
map.put("map", mapArgumentAggregationMethodReference().forOperator("$map") //
|
||||
@@ -138,6 +146,15 @@ public class MethodReferenceNode extends ExpressionNode {
|
||||
map.put("millisecond", singleArgumentAggregationMethodReference().forOperator("$millisecond"));
|
||||
map.put("dateToString", mapArgumentAggregationMethodReference().forOperator("$dateToString") //
|
||||
.mappingParametersTo("format", "date"));
|
||||
map.put("dateFromString", mapArgumentAggregationMethodReference().forOperator("$dateFromString") //
|
||||
.mappingParametersTo("dateString", "format", "timezone", "onError", "onNull"));
|
||||
map.put("dateFromParts", mapArgumentAggregationMethodReference().forOperator("$dateFromParts")
|
||||
.mappingParametersTo("year", "month", "day", "hour", "minute", "second", "milliseconds", "timezone"));
|
||||
map.put("isoDateFromParts",
|
||||
mapArgumentAggregationMethodReference().forOperator("$dateFromParts").mappingParametersTo("isoWeekYear",
|
||||
"isoWeek", "isoDayOfWeek", "hour", "minute", "second", "milliseconds", "timezone"));
|
||||
map.put("dateToParts", mapArgumentAggregationMethodReference().forOperator("$dateToParts") //
|
||||
.mappingParametersTo("date", "timezone", "iso8601"));
|
||||
map.put("isoDayOfWeek", singleArgumentAggregationMethodReference().forOperator("$isoDayOfWeek"));
|
||||
map.put("isoWeek", singleArgumentAggregationMethodReference().forOperator("$isoWeek"));
|
||||
map.put("isoWeekYear", singleArgumentAggregationMethodReference().forOperator("$isoWeekYear"));
|
||||
@@ -162,6 +179,24 @@ public class MethodReferenceNode extends ExpressionNode {
|
||||
// TYPE OPERATORS
|
||||
map.put("type", singleArgumentAggregationMethodReference().forOperator("$type"));
|
||||
|
||||
// OBJECT OPERATORS
|
||||
map.put("objectToArray", singleArgumentAggregationMethodReference().forOperator("$objectToArray"));
|
||||
map.put("mergeObjects", arrayArgumentAggregationMethodReference().forOperator("$mergeObjects"));
|
||||
|
||||
// CONVERT OPERATORS
|
||||
map.put("convert", mapArgumentAggregationMethodReference().forOperator("$convert") //
|
||||
.mappingParametersTo("input", "to", "onError", "onNull"));
|
||||
map.put("toBool", singleArgumentAggregationMethodReference().forOperator("$toBool"));
|
||||
map.put("toDate", singleArgumentAggregationMethodReference().forOperator("$toDate"));
|
||||
map.put("toDecimal", singleArgumentAggregationMethodReference().forOperator("$toDecimal"));
|
||||
map.put("toDouble", singleArgumentAggregationMethodReference().forOperator("$toDouble"));
|
||||
map.put("toInt", singleArgumentAggregationMethodReference().forOperator("$toInt"));
|
||||
map.put("toLong", singleArgumentAggregationMethodReference().forOperator("$toLong"));
|
||||
map.put("toObjectId", singleArgumentAggregationMethodReference().forOperator("$toObjectId"));
|
||||
map.put("toString", singleArgumentAggregationMethodReference().forOperator("$toString"));
|
||||
|
||||
|
||||
|
||||
FUNCTIONS = Collections.unmodifiableMap(map);
|
||||
}
|
||||
|
||||
|
||||
@@ -719,6 +719,216 @@ public class SpelExpressionTransformerUnitTests {
|
||||
assertThat(transform("type(a)"), is(Document.parse("{ \"$type\" : \"$a\"}")));
|
||||
}
|
||||
|
||||
@Test // DATAMONGO-2077
|
||||
public void shouldRenderArrayToObjectWithFieldReference() {
|
||||
assertThat(transform("arrayToObject(field)"), is(Document.parse("{ \"$arrayToObject\" : \"$field\"}")));
|
||||
}
|
||||
|
||||
@Test // DATAMONGO-2077
|
||||
public void shouldRenderArrayToObjectWithArray() {
|
||||
|
||||
assertThat(transform("arrayToObject(new String[]{'key', 'value'})"),
|
||||
is(Document.parse("{ \"$arrayToObject\" : [\"key\", \"value\"]}")));
|
||||
}
|
||||
|
||||
@Test // DATAMONGO-2077
|
||||
public void shouldRenderObjectToArrayWithFieldReference() {
|
||||
assertThat(transform("objectToArray(field)"), is(Document.parse("{ \"$objectToArray\" : \"$field\"}")));
|
||||
}
|
||||
|
||||
@Test // DATAMONGO-2077
|
||||
public void shouldRenderMergeObjects() {
|
||||
|
||||
assertThat(transform("mergeObjects(field1, $$ROOT)"),
|
||||
is(Document.parse("{ \"$mergeObjects\" : [\"$field1\", \"$$ROOT\"]}")));
|
||||
}
|
||||
|
||||
@Test // DATAMONGO-2077
|
||||
public void shouldRenderTrimWithoutChars() {
|
||||
assertThat(transform("trim(field)"), is(Document.parse("{ \"$trim\" : {\"input\" : \"$field\"}}")));
|
||||
}
|
||||
|
||||
@Test // DATAMONGO-2077
|
||||
public void shouldRenderTrimWithChars() {
|
||||
|
||||
assertThat(transform("trim(field, 'ie')"),
|
||||
is(Document.parse("{ \"$trim\" : {\"input\" : \"$field\", \"chars\" : \"ie\" }}")));
|
||||
}
|
||||
|
||||
@Test // DATAMONGO-2077
|
||||
public void shouldRenderTrimWithCharsFromFieldReference() {
|
||||
|
||||
assertThat(transform("trim(field1, field2)"),
|
||||
is(Document.parse("{ \"$trim\" : {\"input\" : \"$field1\", \"chars\" : \"$field2\" }}")));
|
||||
}
|
||||
|
||||
@Test // DATAMONGO-2077
|
||||
public void shouldRenderLtrimWithoutChars() {
|
||||
assertThat(transform("ltrim(field)"), is(Document.parse("{ \"$ltrim\" : {\"input\" : \"$field\"}}")));
|
||||
}
|
||||
|
||||
@Test // DATAMONGO-2077
|
||||
public void shouldRenderLtrimWithChars() {
|
||||
|
||||
assertThat(transform("ltrim(field, 'ie')"),
|
||||
is(Document.parse("{ \"$ltrim\" : {\"input\" : \"$field\", \"chars\" : \"ie\" }}")));
|
||||
}
|
||||
|
||||
@Test // DATAMONGO-2077
|
||||
public void shouldRenderLtrimWithCharsFromFieldReference() {
|
||||
|
||||
assertThat(transform("ltrim(field1, field2)"),
|
||||
is(Document.parse("{ \"$ltrim\" : {\"input\" : \"$field1\", \"chars\" : \"$field2\" }}")));
|
||||
}
|
||||
|
||||
@Test // DATAMONGO-2077
|
||||
public void shouldRenderRtrimWithoutChars() {
|
||||
assertThat(transform("rtrim(field)"), is(Document.parse("{ \"$rtrim\" : {\"input\" : \"$field\"}}")));
|
||||
}
|
||||
|
||||
@Test // DATAMONGO-2077
|
||||
public void shouldRenderRtrimWithChars() {
|
||||
|
||||
assertThat(transform("rtrim(field, 'ie')"),
|
||||
is(Document.parse("{ \"$rtrim\" : {\"input\" : \"$field\", \"chars\" : \"ie\" }}")));
|
||||
}
|
||||
|
||||
@Test // DATAMONGO-2077
|
||||
public void shouldRenderRtrimWithCharsFromFieldReference() {
|
||||
|
||||
assertThat(transform("rtrim(field1, field2)"),
|
||||
is(Document.parse("{ \"$rtrim\" : {\"input\" : \"$field1\", \"chars\" : \"$field2\" }}")));
|
||||
}
|
||||
|
||||
@Test // DATAMONGO-2077
|
||||
public void shouldRenderConvertWithoutOptionalParameters() {
|
||||
|
||||
assertThat(transform("convert(field, 'string')"),
|
||||
is(Document.parse("{ \"$convert\" : {\"input\" : \"$field\", \"to\" : \"string\" }}")));
|
||||
}
|
||||
|
||||
@Test // DATAMONGO-2077
|
||||
public void shouldRenderConvertWithOnError() {
|
||||
|
||||
assertThat(transform("convert(field, 'int', 'Not an integer.')"), is(Document
|
||||
.parse("{ \"$convert\" : {\"input\" : \"$field\", \"to\" : \"int\", \"onError\" : \"Not an integer.\" }}")));
|
||||
}
|
||||
|
||||
@Test // DATAMONGO-2077
|
||||
public void shouldRenderConvertWithOnErrorOnNull() {
|
||||
|
||||
assertThat(transform("convert(field, 'int', 'Not an integer.', -1)"), is(Document.parse(
|
||||
"{ \"$convert\" : {\"input\" : \"$field\", \"to\" : \"int\", \"onError\" : \"Not an integer.\", \"onNull\" : -1 }}")));
|
||||
}
|
||||
|
||||
@Test // DATAMONGO-2077
|
||||
public void shouldRenderToBool() {
|
||||
assertThat(transform("toBool(field)"), is(Document.parse("{ \"$toBool\" : \"$field\"}")));
|
||||
}
|
||||
|
||||
@Test // DATAMONGO-2077
|
||||
public void shouldRenderToDate() {
|
||||
assertThat(transform("toDate(field)"), is(Document.parse("{ \"$toDate\" : \"$field\"}")));
|
||||
}
|
||||
|
||||
@Test // DATAMONGO-2077
|
||||
public void shouldRenderToDecimal() {
|
||||
assertThat(transform("toDecimal(field)"), is(Document.parse("{ \"$toDecimal\" : \"$field\"}")));
|
||||
}
|
||||
|
||||
@Test // DATAMONGO-2077
|
||||
public void shouldRenderToDouble() {
|
||||
assertThat(transform("toDouble(field)"), is(Document.parse("{ \"$toDouble\" : \"$field\"}")));
|
||||
}
|
||||
|
||||
@Test // DATAMONGO-2077
|
||||
public void shouldRenderToInt() {
|
||||
assertThat(transform("toInt(field)"), is(Document.parse("{ \"$toInt\" : \"$field\"}")));
|
||||
}
|
||||
|
||||
@Test // DATAMONGO-2077
|
||||
public void shouldRenderToLong() {
|
||||
assertThat(transform("toLong(field)"), is(Document.parse("{ \"$toLong\" : \"$field\"}")));
|
||||
}
|
||||
|
||||
@Test // DATAMONGO-2077
|
||||
public void shouldRenderToObjectId() {
|
||||
assertThat(transform("toObjectId(field)"), is(Document.parse("{ \"$toObjectId\" : \"$field\"}")));
|
||||
}
|
||||
|
||||
@Test // DATAMONGO-2077
|
||||
public void shouldRenderToString() {
|
||||
assertThat(transform("toString(field)"), is(Document.parse("{ \"$toString\" : \"$field\"}")));
|
||||
}
|
||||
|
||||
@Test // DATAMONGO-2077
|
||||
public void shouldRenderDateFromStringWithoutOptionalParameters() {
|
||||
|
||||
assertThat(transform("dateFromString(field)"),
|
||||
is(Document.parse("{ \"$dateFromString\" : {\"dateString\" : \"$field\" }}")));
|
||||
}
|
||||
|
||||
@Test // DATAMONGO-2077
|
||||
public void shouldRenderDateFromStringWithFormat() {
|
||||
|
||||
assertThat(transform("dateFromString(field, 'DD-MM-YYYY')"),
|
||||
is(Document.parse("{ \"$dateFromString\" : {\"dateString\" : \"$field\", \"format\" : \"DD-MM-YYYY\" }}")));
|
||||
}
|
||||
|
||||
@Test // DATAMONGO-2077
|
||||
public void shouldRenderDateFromStringWithFormatAndTimezone() {
|
||||
|
||||
assertThat(transform("dateFromString(field, 'DD-MM-YYYY', 'UTC')"), is(Document.parse(
|
||||
"{ \"$dateFromString\" : {\"dateString\" : \"$field\", \"format\" : \"DD-MM-YYYY\", \"timezone\" : \"UTC\" }}")));
|
||||
}
|
||||
|
||||
@Test // DATAMONGO-2077
|
||||
public void shouldRenderDateFromStringWithFormatTimezoneAndOnError() {
|
||||
|
||||
assertThat(transform("dateFromString(field, 'DD-MM-YYYY', 'UTC', -1)"), is(Document.parse(
|
||||
"{ \"$dateFromString\" : {\"dateString\" : \"$field\", \"format\" : \"DD-MM-YYYY\", \"timezone\" : \"UTC\", \"onError\" : -1 }}")));
|
||||
}
|
||||
|
||||
@Test // DATAMONGO-2077
|
||||
public void shouldRenderDateFromStringWithFormatTimezoneOnErrorAndOnNull() {
|
||||
|
||||
assertThat(transform("dateFromString(field, 'DD-MM-YYYY', 'UTC', -1, -2)"), is(Document.parse(
|
||||
"{ \"$dateFromString\" : {\"dateString\" : \"$field\", \"format\" : \"DD-MM-YYYY\", \"timezone\" : \"UTC\", \"onError\" : -1, \"onNull\" : -2}}")));
|
||||
}
|
||||
|
||||
@Test // DATAMONGO-2077
|
||||
public void shouldRenderDateFromParts() {
|
||||
|
||||
assertThat(transform("dateFromParts(y, m, d, h, mm, s, ms, 'UTC')"), is(Document.parse(
|
||||
"{ \"$dateFromParts\" : {\"year\" : \"$y\", \"month\" : \"$m\", \"day\" : \"$d\", \"hour\" : \"$h\", \"minute\" : \"$mm\", \"second\" : \"$s\", \"milliseconds\" : \"$ms\", \"timezone\" : \"UTC\"}}")));
|
||||
}
|
||||
|
||||
@Test // DATAMONGO-2077
|
||||
public void shouldRenderIsoDateFromParts() {
|
||||
|
||||
assertThat(transform("isoDateFromParts(y, m, d, h, mm, s, ms, 'UTC')"), is(Document.parse(
|
||||
"{ \"$dateFromParts\" : {\"isoWeekYear\" : \"$y\", \"isoWeek\" : \"$m\", \"isoDayOfWeek\" : \"$d\", \"hour\" : \"$h\", \"minute\" : \"$mm\", \"second\" : \"$s\", \"milliseconds\" : \"$ms\", \"timezone\" : \"UTC\"}}")));
|
||||
}
|
||||
|
||||
@Test // DATAMONGO-2077
|
||||
public void shouldRenderDateToParts() {
|
||||
|
||||
assertThat(transform("dateToParts(field, 'UTC', false)"), is(
|
||||
Document.parse("{ \"$dateToParts\" : {\"date\" : \"$field\", \"timezone\" : \"UTC\", \"iso8601\" : false}}")));
|
||||
}
|
||||
|
||||
@Test // DATAMONGO-2077
|
||||
public void shouldRenderIndexOfArray() {
|
||||
|
||||
assertThat(transform("indexOfArray(field, 2)"), is(Document.parse("{ \"$indexOfArray\" : [\"$field\", 2 ]}")));
|
||||
}
|
||||
|
||||
@Test // DATAMONGO-2077
|
||||
public void shouldRenderRange() {
|
||||
|
||||
assertThat(transform("range(0, 10, 2)"), is(Document.parse("{ \"$range\" : [0, 10, 2 ]}")));
|
||||
}
|
||||
|
||||
private Object transform(String expression, Object... params) {
|
||||
Object result = transformer.transform(expression, Aggregation.DEFAULT_CONTEXT, params);
|
||||
return result == null ? null : (!(result instanceof org.bson.Document) ? result.toString() : result);
|
||||
|
||||
Reference in New Issue
Block a user