DATAMONGO-2047 - Update $dateToString and $dateFromString aggregation operators to match MongoDB 4.0 changes.
We added the format and onNull options to DateFromString and changed format to an optional parameter. Original pull request: #593.
This commit is contained in:
committed by
Mark Paluch
parent
7b67ad4f6c
commit
64dc3dbb1d
@@ -22,6 +22,7 @@ import java.util.Map;
|
||||
import org.springframework.lang.Nullable;
|
||||
import org.springframework.util.Assert;
|
||||
import org.springframework.util.ObjectUtils;
|
||||
import org.springframework.util.StringUtils;
|
||||
|
||||
/**
|
||||
* Gateway to {@literal Date} aggregation operations.
|
||||
@@ -178,7 +179,7 @@ public class DateOperators {
|
||||
* Create a {@link Timezone} for the {@link AggregationExpression} resulting in the Olson Timezone Identifier or UTC
|
||||
* Offset.
|
||||
*
|
||||
* @param value the {@link AggregationExpression} resulting in the timezone.
|
||||
* @param expression the {@link AggregationExpression} resulting in the timezone.
|
||||
* @return new instance of {@link Timezone}.
|
||||
*/
|
||||
public static Timezone ofExpression(AggregationExpression expression) {
|
||||
@@ -380,6 +381,17 @@ public class DateOperators {
|
||||
return applyTimezone(DateToString.dateToString(dateReference()).toString(format), timezone);
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates new {@link AggregationExpression} that converts a date object to a string according to the server default
|
||||
* format.
|
||||
*
|
||||
* @return new instance of {@link DateToString}.
|
||||
* @since 2.1
|
||||
*/
|
||||
public DateToString toStringWithDefaultFormat() {
|
||||
return applyTimezone(DateToString.dateToString(dateReference()).defaultFormat(), timezone);
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates new {@link AggregationExpression} that returns the weekday number in ISO 8601-2018 format, ranging from 1
|
||||
* (for Monday) to 7 (for Sunday).
|
||||
@@ -1352,6 +1364,11 @@ public class DateOperators {
|
||||
Assert.notNull(format, "Format must not be null!");
|
||||
return new DateToString(argumentMap(value, format, Timezone.none()));
|
||||
}
|
||||
|
||||
@Override
|
||||
public DateToString defaultFormat() {
|
||||
return new DateToString(argumentMap(value, null, Timezone.none()));
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
@@ -1395,15 +1412,55 @@ public class DateOperators {
|
||||
return new DateToString(argumentMap(get("date"), get("format"), timezone));
|
||||
}
|
||||
|
||||
/**
|
||||
* Optionally specify the value to return when the date is {@literal null} or missing. <br />
|
||||
* <strong>NOTE:</strong> Requires MongoDB 4.0 or later.
|
||||
*
|
||||
* @param value must not be {@literal null}.
|
||||
* @return new instance of {@link DateToString}.
|
||||
* @since 2.1
|
||||
*/
|
||||
public DateToString onNullReturn(Object value) {
|
||||
return new DateToString(append("onNull", value));
|
||||
}
|
||||
|
||||
/**
|
||||
* Optionally specify the field holding the value to return when the date is {@literal null} or missing. <br />
|
||||
* <strong>NOTE:</strong> Requires MongoDB 4.0 or later.
|
||||
*
|
||||
* @param fieldReference must not be {@literal null}.
|
||||
* @return new instance of {@link DateToString}.
|
||||
* @since 2.1
|
||||
*/
|
||||
public DateToString onNullReturnValueOf(String fieldReference) {
|
||||
return onNullReturn(Fields.field(fieldReference));
|
||||
}
|
||||
|
||||
/**
|
||||
* Optionally specify the expression to evaluate and return when the date is {@literal null} or missing. <br />
|
||||
* <strong>NOTE:</strong> Requires MongoDB 4.0 or later.
|
||||
*
|
||||
* @param expression must not be {@literal null}.
|
||||
* @return new instance of {@link DateToString}.
|
||||
* @since 2.1
|
||||
*/
|
||||
public DateToString onNullReturnValueOf(AggregationExpression expression) {
|
||||
return onNullReturn(expression);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected String getMongoMethod() {
|
||||
return "$dateToString";
|
||||
}
|
||||
|
||||
private static java.util.Map<String, Object> argumentMap(Object date, String format, Timezone timezone) {
|
||||
private static java.util.Map<String, Object> argumentMap(Object date, @Nullable String format, Timezone timezone) {
|
||||
|
||||
java.util.Map<String, Object> args = new LinkedHashMap<String, Object>(2);
|
||||
args.put("format", format);
|
||||
|
||||
if (StringUtils.hasText(format)) {
|
||||
args.put("format", format);
|
||||
}
|
||||
|
||||
args.put("date", date);
|
||||
|
||||
if (!ObjectUtils.nullSafeEquals(timezone, Timezone.none())) {
|
||||
@@ -1421,6 +1478,16 @@ public class DateOperators {
|
||||
* @return
|
||||
*/
|
||||
DateToString toString(String format);
|
||||
|
||||
/**
|
||||
* Creates new {@link DateToString} using the server default string format ({@code %Y-%m-%dT%H:%M:%S.%LZ}) for
|
||||
* dates. <br />
|
||||
* <strong>NOTE:</strong> Requires MongoDB 4.0 or later.
|
||||
*
|
||||
* @return new instance of {@link DateToString}.
|
||||
* @since 2.1
|
||||
*/
|
||||
DateToString defaultFormat();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2269,6 +2336,20 @@ public class DateOperators {
|
||||
return new DateFromString(appendTimezone(argumentMap(), timezone));
|
||||
}
|
||||
|
||||
/**
|
||||
* Optionally set the date format to use. If not specified {@code %Y-%m-%dT%H:%M:%S.%LZ} is used.<br />
|
||||
* <strong>NOTE:</strong> Requires MongoDB 4.0 or later.
|
||||
*
|
||||
* @param format must not be {@literal null}.
|
||||
* @return new instance of {@link DateFromString}.
|
||||
* @throws IllegalArgumentException if given {@literal format} is {@literal null}.
|
||||
*/
|
||||
public DateFromString withFormat(String format) {
|
||||
|
||||
Assert.notNull(format, "Format must not be null!");
|
||||
return new DateFromString(append("format", format));
|
||||
}
|
||||
|
||||
@Override
|
||||
protected String getMongoMethod() {
|
||||
return "$dateFromString";
|
||||
|
||||
@@ -1204,6 +1204,18 @@ public class ProjectionOperation implements FieldsExposingAggregationOperation {
|
||||
return this.operation.and(DateOperators.DateToString.dateOf(getRequiredName()).toString(format));
|
||||
}
|
||||
|
||||
/**
|
||||
* Generates a {@code $dateToString} expression that takes the date representation of the previously mentioned field
|
||||
* using the server default format. <br />
|
||||
* strong>NOTE:</strong> Requires MongoDB 4.0 or later.
|
||||
*
|
||||
* @return
|
||||
* @since 2.1
|
||||
*/
|
||||
public ProjectionOperationBuilder dateAsFormattedString() {
|
||||
return this.operation.and(DateOperators.DateToString.dateOf(getRequiredName()).defaultFormat());
|
||||
}
|
||||
|
||||
/**
|
||||
* Generates a {@code $let} expression that binds variables for use in the specified expression, and returns the
|
||||
* result of the expression.
|
||||
|
||||
@@ -1317,6 +1317,14 @@ public class ProjectionOperationUnitTests {
|
||||
Document.parse("{ $project: { time: { $dateToString: { format: \"%H:%M:%S:%L\", date: \"$date\" } } } }"));
|
||||
}
|
||||
|
||||
@Test // DATAMONGO-2047
|
||||
public void shouldRenderDateToStringWithoutFormatOption() {
|
||||
|
||||
Document agg = project().and("date").dateAsFormattedString().as("time").toDocument(Aggregation.DEFAULT_CONTEXT);
|
||||
|
||||
assertThat(agg).isEqualTo(Document.parse("{ $project: { time: { $dateToString: { date: \"$date\" } } } }"));
|
||||
}
|
||||
|
||||
@Test // DATAMONGO-1536
|
||||
public void shouldRenderDateToStringAggregationExpression() {
|
||||
|
||||
@@ -1338,6 +1346,17 @@ public class ProjectionOperationUnitTests {
|
||||
"{ $project: { time: { $dateToString: { format: \"%H:%M:%S:%L\", date: \"$date\", \"timezone\" : \"America/Chicago\" } } } } } }"));
|
||||
}
|
||||
|
||||
@Test // DATAMONGO-2047
|
||||
public void shouldRenderDateToStringWithOnNull() {
|
||||
|
||||
Document agg = project()
|
||||
.and(DateOperators.dateOf("date").toStringWithDefaultFormat().onNullReturnValueOf("fallback-field")).as("time")
|
||||
.toDocument(Aggregation.DEFAULT_CONTEXT);
|
||||
|
||||
assertThat(agg).isEqualTo(Document
|
||||
.parse("{ $project: { time: { $dateToString: { date: \"$date\", \"onNull\" : \"$fallback-field\" } } } }"));
|
||||
}
|
||||
|
||||
@Test // DATAMONGO-1536
|
||||
public void shouldRenderSumAggregationExpression() {
|
||||
|
||||
@@ -2037,6 +2056,16 @@ public class ProjectionOperationUnitTests {
|
||||
"{ $project : { newDate: { $dateFromString: { dateString : \"2017-02-08T12:10:40.787\", timezone : \"America/Chicago\" } } } }"));
|
||||
}
|
||||
|
||||
@Test // DATAMONGO-2047
|
||||
public void shouldRenderDateFromStringWithFormat() {
|
||||
|
||||
Document agg = project().and(DateOperators.dateFromString("2017-02-08T12:10:40.787").withFormat("dd/mm/yyyy"))
|
||||
.as("newDate").toDocument(Aggregation.DEFAULT_CONTEXT);
|
||||
|
||||
assertThat(agg).isEqualTo(Document.parse(
|
||||
"{ $project : { newDate: { $dateFromString: { dateString : \"2017-02-08T12:10:40.787\", format : \"dd/mm/yyyy\" } } } }"));
|
||||
}
|
||||
|
||||
private static Document exctractOperation(String field, Document fromProjectClause) {
|
||||
return (Document) fromProjectClause.get(field);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user