Browse Source

Add support for `$tan` and `$tanh` aggregation operators.

Closes: #3730
Original pull request: #3755.
pull/3765/head
Christoph Strobl 5 years ago committed by Mark Paluch
parent
commit
73d5886aae
No known key found for this signature in database
GPG Key ID: 4406B84C1661DCD1
  1. 251
      spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/aggregation/ArithmeticOperators.java
  2. 2
      spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/spel/MethodReferenceNode.java
  3. 29
      spring-data-mongodb/src/test/java/org/springframework/data/mongodb/core/aggregation/ArithmeticOperatorsUnitTests.java
  4. 10
      spring-data-mongodb/src/test/java/org/springframework/data/mongodb/core/aggregation/SpelExpressionTransformerUnitTests.java

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

@ -719,6 +719,51 @@ public class ArithmeticOperators { @@ -719,6 +719,51 @@ public class ArithmeticOperators {
return usesFieldRef() ? Sinh.sinhOf(fieldReference, unit) : Sinh.sinhOf(expression, unit);
}
/**
* Creates new {@link AggregationExpression} that calculates the tangent of a numeric value given in
* {@link AngularDimension#RADIANS radians}.
*
* @return new instance of {@link Sin}.
* @since 3.3
*/
public Tan tan() {
return tan(AngularDimension.RADIANS);
}
/**
* Creates new {@link AggregationExpression} that calculates the tangent of a numeric value in the given
* {@link AngularDimension unit}.
*
* @param unit the unit of measure.
* @return new instance of {@link Sin}.
* @since 3.3
*/
public Tan tan(AngularDimension unit) {
return usesFieldRef() ? Tan.tanOf(fieldReference, unit) : Tan.tanOf(expression, unit);
}
/**
* Creates new {@link AggregationExpression} that calculates the hyperbolic tangent of a numeric value given in
* {@link AngularDimension#RADIANS radians}.
*
* @return new instance of {@link Sin}.
* @since 3.3
*/
public Tanh tanh() {
return tanh(AngularDimension.RADIANS);
}
/**
* Creates new {@link AggregationExpression} that calculates the hyperbolic tangent of a numeric value.
*
* @param unit the unit of measure.
* @return new instance of {@link Sin}.
* @since 3.3
*/
public Tanh tanh(AngularDimension unit) {
return usesFieldRef() ? Tanh.tanhOf(fieldReference, unit) : Tanh.tanhOf(expression, unit);
}
private boolean usesFieldRef() {
return fieldReference != null;
}
@ -2153,4 +2198,210 @@ public class ArithmeticOperators { @@ -2153,4 +2198,210 @@ public class ArithmeticOperators {
return "$sinh";
}
}
/**
* An {@link AggregationExpression expression} that calculates the tangent of a value that is measured in radians.
*
* @author Christoph Strobl
* @since 3.3
*/
public static class Tan extends AbstractAggregationExpression {
private Tan(Object value) {
super(value);
}
/**
* Creates a new {@link AggregationExpression} that calculates the tangent of a value that is measured in
* {@link AngularDimension#RADIANS radians}.
* <p />
* Use {@code tanOf("angle", DEGREES)} as shortcut for
*
* <pre>
* { $tan : { $degreesToRadians : "$angle" } }
* </pre>
*
* .
*
* @param fieldReference the name of the {@link Field field} that resolves to a numeric value.
* @return new instance of {@link Tan}.
*/
public static Tan tanOf(String fieldReference) {
return tanOf(fieldReference, AngularDimension.RADIANS);
}
/**
* Creates a new {@link AggregationExpression} that calculates the tangent of a value that is measured in the given
* {@link AngularDimension unit}.
*
* @param fieldReference the name of the {@link Field field} that resolves to a numeric value.
* @param unit the unit of measure used by the value of the given field.
* @return new instance of {@link Tan}.
*/
public static Tan tanOf(String fieldReference, AngularDimension unit) {
return tan(Fields.field(fieldReference), unit);
}
/**
* Creates a new {@link AggregationExpression} that calculates the tangent of a value that is measured in
* {@link AngularDimension#RADIANS}.
*
* @param expression the {@link AggregationExpression expression} that resolves to a numeric value.
* @return new instance of {@link Tan}.
*/
public static Tan tanOf(AggregationExpression expression) {
return tanOf(expression, AngularDimension.RADIANS);
}
/**
* Creates a new {@link AggregationExpression} that calculates the tangent of a value that is measured in the given
* {@link AngularDimension unit}.
*
* @param expression the {@link AggregationExpression expression} that resolves to a numeric value.
* @param unit the unit of measure used by the value of the given field.
* @return new instance of {@link Tan}.
*/
public static Tan tanOf(AggregationExpression expression, AngularDimension unit) {
return tan(expression, unit);
}
/**
* Creates a new {@link AggregationExpression} that calculates the tangent of a value that is measured in
* {@link AngularDimension#RADIANS}.
*
* @param value anything ({@link Field field}, {@link AggregationExpression expression}, ...) that resolves to a
* numeric value
* @return new instance of {@link Tan}.
*/
public static Tan tan(Object value) {
return tan(value, AngularDimension.RADIANS);
}
/**
* Creates a new {@link AggregationExpression} that calculates the tangent of a value that is measured in the given
* {@link AngularDimension unit}.
*
* @param value anything ({@link Field field}, {@link AggregationExpression expression}, ...) that resolves to a
* numeric value.
* @param unit the unit of measure used by the value of the given field.
* @return new instance of {@link Tan}.
*/
public static Tan tan(Object value, AngularDimension unit) {
if (ObjectUtils.nullSafeEquals(AngularDimension.DEGREES, unit)) {
return new Tan(ConvertOperators.DegreesToRadians.degreesToRadians(value));
}
return new Tan(value);
}
@Override
protected String getMongoMethod() {
return "$tan";
}
}
/**
* An {@link AggregationExpression expression} that calculates the hyperbolic tangent of a value that is measured in
* {@link AngularDimension#RADIANS}.
*
* @author Christoph Strobl
* @since 3.3
*/
public static class Tanh extends AbstractAggregationExpression {
private Tanh(Object value) {
super(value);
}
/**
* Creates a new {@link AggregationExpression} that calculates the hyperbolic tangent of a value that is measured in
* {@link AngularDimension#RADIANS}.
*
* @param fieldReference the name of the {@link Field field} that resolves to a numeric value.
* @return new instance of {@link Tanh}.
*/
public static Tanh tanhOf(String fieldReference) {
return tanhOf(fieldReference, AngularDimension.RADIANS);
}
/**
* Creates a new {@link AggregationExpression} that calculates the hyperbolic tangent of a value that is measured in
* the given {@link AngularDimension unit}.
* <p />
* Use {@code tanhOf("angle", DEGREES)} as shortcut for
*
* <pre>
* { $tanh : { $degreesToRadians : "$angle" } }
* </pre>
*
* .
*
* @param fieldReference the name of the {@link Field field} that resolves to a numeric value.
* @param unit the unit of measure used by the value of the given field.
* @return new instance of {@link Tanh}.
*/
public static Tanh tanhOf(String fieldReference, AngularDimension unit) {
return tanh(Fields.field(fieldReference), unit);
}
/**
* Creates a new {@link AggregationExpression} that calculates the hyperbolic tangent of a value that is measured in
* {@link AngularDimension#RADIANS}.
* <p />
* Use {@code sinhOf("angle", DEGREES)} as shortcut for eg.
* {@code sinhOf(ConvertOperators.valueOf("angle").degreesToRadians())}.
*
* @param expression the {@link AggregationExpression expression} that resolves to a numeric value.
* @return new instance of {@link Tanh}.
*/
public static Tanh tanhOf(AggregationExpression expression) {
return tanhOf(expression, AngularDimension.RADIANS);
}
/**
* Creates a new {@link AggregationExpression} that calculates the hyperbolic tangent of a value that is measured in
* the given {@link AngularDimension unit}.
*
* @param expression the {@link AggregationExpression expression} that resolves to a numeric value.
* @param unit the unit of measure used by the value of the given field.
* @return new instance of {@link Tanh}.
*/
public static Tanh tanhOf(AggregationExpression expression, AngularDimension unit) {
return tanh(expression, unit);
}
/**
* Creates a new {@link AggregationExpression} that calculates the hyperbolic tangent of a value that is measured in
* {@link AngularDimension#RADIANS}.
*
* @param value anything ({@link Field field}, {@link AggregationExpression expression}, ...) that resolves to a
* numeric value.
* @return new instance of {@link Tanh}.
*/
public static Tanh tanh(Object value) {
return tanh(value, AngularDimension.RADIANS);
}
/**
* Creates a new {@link AggregationExpression} that calculates the hyperbolic tangent of a value that is measured in
* the given {@link AngularDimension unit}.
*
* @param value anything ({@link Field field}, {@link AggregationExpression expression}, ...) that resolves to a
* numeric value
* @param unit the unit of measure used by the value of the given field.
* @return new instance of {@link Tanh}.
*/
public static Tanh tanh(Object value, AngularDimension unit) {
if (ObjectUtils.nullSafeEquals(AngularDimension.DEGREES, unit)) {
return new Tanh(ConvertOperators.DegreesToRadians.degreesToRadians(value));
}
return new Tanh(value);
}
@Override
protected String getMongoMethod() {
return "$tanh";
}
}
}

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

@ -95,6 +95,8 @@ public class MethodReferenceNode extends ExpressionNode { @@ -95,6 +95,8 @@ public class MethodReferenceNode extends ExpressionNode {
map.put("integral", mapArgRef().forOperator("$integral").mappingParametersTo("input", "unit"));
map.put("sin", singleArgRef().forOperator("$sin"));
map.put("sinh", singleArgRef().forOperator("$sinh"));
map.put("tan", singleArgRef().forOperator("$tan"));
map.put("tanh", singleArgRef().forOperator("$tanh"));
// STRING OPERATORS
map.put("concat", arrayArgRef().forOperator("$concat"));

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

@ -109,4 +109,33 @@ class ArithmeticOperatorsUnitTests { @@ -109,4 +109,33 @@ class ArithmeticOperatorsUnitTests {
assertThat(valueOf("angle").sinh(AngularDimension.DEGREES).toDocument(Aggregation.DEFAULT_CONTEXT))
.isEqualTo(Document.parse("{ $sinh : { $degreesToRadians : \"$angle\" } }"));
}
@Test // GH-3730
void rendersTan() {
assertThat(valueOf("angle").tan().toDocument(Aggregation.DEFAULT_CONTEXT))
.isEqualTo(Document.parse("{ $tan : \"$angle\" }"));
}
@Test // GH-3730
void rendersTanWithValueInDegrees() {
assertThat(valueOf("angle").tan(AngularDimension.DEGREES).toDocument(Aggregation.DEFAULT_CONTEXT))
.isEqualTo(Document.parse("{ $tan : { $degreesToRadians : \"$angle\" } }"));
}
@Test // GH-3730
void rendersTanh() {
assertThat(valueOf("angle").tanh().toDocument(Aggregation.DEFAULT_CONTEXT))
.isEqualTo(Document.parse("{ $tanh : \"$angle\" }"));
}
@Test // GH-3730
void rendersTanhWithValueInDegrees() {
assertThat(valueOf("angle").tanh(AngularDimension.DEGREES).toDocument(Aggregation.DEFAULT_CONTEXT))
.isEqualTo(Document.parse("{ $tanh : { $degreesToRadians : \"$angle\" } }"));
}
}

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

@ -1014,6 +1014,16 @@ public class SpelExpressionTransformerUnitTests { @@ -1014,6 +1014,16 @@ public class SpelExpressionTransformerUnitTests {
assertThat(transform("sinh(angle)")).isEqualTo(Document.parse("{ \"$sinh\" : \"$angle\"}"));
}
@Test // GH-3730
void shouldRenderTan() {
assertThat(transform("tan(angle)")).isEqualTo(Document.parse("{ \"$tan\" : \"$angle\"}"));
}
@Test // GH-3730
void shouldRenderTanh() {
assertThat(transform("tanh(angle)")).isEqualTo(Document.parse("{ \"$tanh\" : \"$angle\"}"));
}
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);

Loading…
Cancel
Save