Browse Source

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.
pull/662/head
Christoph Strobl 7 years ago committed by Mark Paluch
parent
commit
488462d5b3
  1. 86
      spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/aggregation/DateOperators.java
  2. 12
      spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/aggregation/ProjectionOperation.java
  3. 29
      spring-data-mongodb/src/test/java/org/springframework/data/mongodb/core/aggregation/ProjectionOperationUnitTests.java

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

@ -21,6 +21,7 @@ import java.util.Map;
import org.springframework.util.Assert; import org.springframework.util.Assert;
import org.springframework.util.ObjectUtils; import org.springframework.util.ObjectUtils;
import org.springframework.util.StringUtils;
/** /**
* Gateway to {@literal Date} aggregation operations. * Gateway to {@literal Date} aggregation operations.
@ -175,7 +176,7 @@ public class DateOperators {
* Create a {@link Timezone} for the {@link AggregationExpression} resulting in the Olson Timezone Identifier or UTC * Create a {@link Timezone} for the {@link AggregationExpression} resulting in the Olson Timezone Identifier or UTC
* Offset. * 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}. * @return new instance of {@link Timezone}.
*/ */
public static Timezone ofExpression(AggregationExpression expression) { public static Timezone ofExpression(AggregationExpression expression) {
@ -375,6 +376,17 @@ public class DateOperators {
return applyTimezone(DateToString.dateToString(dateReference()).toString(format), timezone); 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 1.10.15
*/
public DateToString toStringWithDefaultFormat() {
return applyTimezone(DateToString.dateToString(dateReference()).defaultFormat(), timezone);
}
/** /**
* Creates new {@link AggregationExpression} that returns the weekday number in ISO 8601 format, ranging from 1 (for * Creates new {@link AggregationExpression} that returns the weekday number in ISO 8601 format, ranging from 1 (for
* Monday) to 7 (for Sunday). * Monday) to 7 (for Sunday).
@ -1344,6 +1356,11 @@ public class DateOperators {
Assert.notNull(format, "Format must not be null!"); Assert.notNull(format, "Format must not be null!");
return new DateToString(argumentMap(value, format, Timezone.none())); return new DateToString(argumentMap(value, format, Timezone.none()));
} }
@Override
public DateToString defaultFormat() {
return new DateToString(argumentMap(value, null, Timezone.none()));
}
}; };
} }
@ -1387,6 +1404,42 @@ public class DateOperators {
return new DateToString(argumentMap(get("date"), (String) get("format"), timezone)); return new DateToString(argumentMap(get("date"), (String) 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 1.10.15
*/
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 1.10.15
*/
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 1.10.15
*/
public DateToString onNullReturnValueOf(AggregationExpression expression) {
return onNullReturn(expression);
}
@Override @Override
protected String getMongoMethod() { protected String getMongoMethod() {
return "$dateToString"; return "$dateToString";
@ -1395,7 +1448,11 @@ public class DateOperators {
private static java.util.Map<String, Object> argumentMap(Object date, String format, Timezone timezone) { private static java.util.Map<String, Object> argumentMap(Object date, String format, Timezone timezone) {
java.util.Map<String, Object> args = new LinkedHashMap<String, Object>(2); 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); args.put("date", date);
if (!ObjectUtils.nullSafeEquals(timezone, Timezone.none())) { if (!ObjectUtils.nullSafeEquals(timezone, Timezone.none())) {
@ -1413,6 +1470,16 @@ public class DateOperators {
* @return * @return
*/ */
DateToString toString(String format); 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 1.10.15
*/
DateToString defaultFormat();
} }
} }
@ -2278,6 +2345,21 @@ public class DateOperators {
return new DateFromString(appendTimezone(argumentMap(), timezone)); 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}.
* @since 1.10.15
*/
public DateFromString withFormat(String format) {
Assert.notNull(format, "Format must not be null!");
return new DateFromString(append("format", format));
}
@Override @Override
protected String getMongoMethod() { protected String getMongoMethod() {
return "$dateFromString"; return "$dateFromString";

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

@ -1210,6 +1210,18 @@ public class ProjectionOperation implements FieldsExposingAggregationOperation {
return this.operation.and(DateOperators.DateToString.dateOf(name).toString(format)); return this.operation.and(DateOperators.DateToString.dateOf(name).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 1.10.15
*/
public ProjectionOperationBuilder dateAsFormattedString() {
return this.operation.and(DateOperators.DateToString.dateOf(name).defaultFormat());
}
/** /**
* Generates a {@code $let} expression that binds variables for use in the specified expression, and returns the * Generates a {@code $let} expression that binds variables for use in the specified expression, and returns the
* result of the expression. * result of the expression.

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

@ -1283,6 +1283,14 @@ public class ProjectionOperationUnitTests {
is(JSON.parse("{ $project: { time: { $dateToString: { format: \"%H:%M:%S:%L\", date: \"$date\" } } } }"))); is(JSON.parse("{ $project: { time: { $dateToString: { format: \"%H:%M:%S:%L\", date: \"$date\" } } } }")));
} }
@Test // DATAMONGO-2047
public void shouldRenderDateToStringWithoutFormatOption() {
DBObject agg = project().and("date").dateAsFormattedString().as("time").toDBObject(Aggregation.DEFAULT_CONTEXT);
assertThat(agg, is(JSON.parse("{ $project: { time: { $dateToString: { date: \"$date\" } } } }")));
}
@Test // DATAMONGO-1536 @Test // DATAMONGO-1536
public void shouldRenderDateToStringAggregationExpression() { public void shouldRenderDateToStringAggregationExpression() {
@ -1304,6 +1312,17 @@ public class ProjectionOperationUnitTests {
"{ $project: { time: { $dateToString: { format: \"%H:%M:%S:%L\", date: \"$date\", \"timezone\" : \"America/Chicago\" } } } } } }"))); "{ $project: { time: { $dateToString: { format: \"%H:%M:%S:%L\", date: \"$date\", \"timezone\" : \"America/Chicago\" } } } } } }")));
} }
@Test // DATAMONGO-2047
public void shouldRenderDateToStringWithOnNull() {
DBObject agg = project()
.and(DateOperators.dateOf("date").toStringWithDefaultFormat().onNullReturnValueOf("fallback-field")).as("time")
.toDBObject(Aggregation.DEFAULT_CONTEXT);
assertThat(agg, is(JSON
.parse("{ $project: { time: { $dateToString: { date: \"$date\", \"onNull\" : \"$fallback-field\" } } } }")));
}
@Test // DATAMONGO-1536 @Test // DATAMONGO-1536
public void shouldRenderSumAggregationExpression() { public void shouldRenderSumAggregationExpression() {
@ -1997,6 +2016,16 @@ public class ProjectionOperationUnitTests {
"{ $project : { newDate: { $dateFromString: { dateString : \"2017-02-08T12:10:40.787\", timezone : \"America/Chicago\" } } } }"))); "{ $project : { newDate: { $dateFromString: { dateString : \"2017-02-08T12:10:40.787\", timezone : \"America/Chicago\" } } } }")));
} }
@Test // DATAMONGO-2047
public void shouldRenderDateFromStringWithFormat() {
DBObject agg = project().and(DateOperators.dateFromString("2017-02-08T12:10:40.787").withFormat("dd/mm/yyyy"))
.as("newDate").toDBObject(Aggregation.DEFAULT_CONTEXT);
assertThat(agg, is(JSON.parse(
"{ $project : { newDate: { $dateFromString: { dateString : \"2017-02-08T12:10:40.787\", format : \"dd/mm/yyyy\" } } } }")));
}
private static DBObject exctractOperation(String field, DBObject fromProjectClause) { private static DBObject exctractOperation(String field, DBObject fromProjectClause) {
return (DBObject) fromProjectClause.get(field); return (DBObject) fromProjectClause.get(field);
} }

Loading…
Cancel
Save