Skip to content

DATAMONGO-1530: support missing pipeline operators available in Mongo… #410

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
wants to merge 1 commit into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -15,32 +15,87 @@
*/
package org.springframework.data.mongodb.core.spel;

import org.springframework.expression.spel.ExpressionState;
import org.springframework.expression.spel.ast.MethodReference;

import java.util.Collections;
import java.util.HashMap;
import java.util.Map;

import org.springframework.expression.spel.ExpressionState;
import org.springframework.expression.spel.ast.MethodReference;

/**
* An {@link ExpressionNode} representing a method reference.
*
*
* @author Oliver Gierke
* @author Thomas Darimont
* @author Sebastien Gerard
*/
public class MethodReferenceNode extends ExpressionNode {

private static final Map<String, String> FUNCTIONS;

static {

Map<String, String> map = new HashMap<String, String>();

map.put("and", "$and"); // Returns true only when all its expressions evaluate to true.
map.put("or", "$or"); // Returns true when any of its expressions evaluates to true.
map.put("not", "$not"); // Returns the boolean value that is the opposite of its argument expression.

map.put("setEquals", "$setEquals"); // Returns true if the input sets have the same distinct elements.
map.put("setIntersection", "$setIntersection"); // Returns a set with elements that appear in all of the input sets.
map.put("setUnion", "$setUnion"); // Returns a set with elements that appear in any of the input sets.
map.put("setDifference", "$setDifference"); // Returns a set with elements that appear in the 1st set but not in the 2nd.
map.put("setIsSubset", "$setIsSubset"); // Returns true if all elements of the 1st set appear in the 2nd set.
map.put("anyElementTrue", "$anyElementTrue"); // Returns whether any elements of a set evaluate to true.
map.put("allElementsTrue", "$allElementsTrue"); // Returns whether no element of a set evaluates to false.

map.put("cmp", "$cmp"); // Returns: 0 if the two values are equivalent, 1 if the first value is greater than the
// second, and -1 if the first value is less than the second.
map.put("eq", "$eq"); // Returns true if the values are equivalent.
map.put("gt", "$gt"); // Returns true if the first value is greater than the second.
map.put("gte", "$gte"); // Returns true if the first value is greater than or equal to the second.
map.put("lt", "$lt"); // Returns true if the first value is less than the second.
map.put("lte", "$lte"); // Returns true if the first value is less than or equal to the second.
map.put("ne", "$ne"); // Returns true if the values are not equivalent.

map.put("abs", "$abs"); // Returns the absolute value of a number.;
map.put("add", "$add"); // Adds numbers to return the sum, or adds numbers and a date to return a new date.
map.put("ceil", "$ceil"); // Returns the smallest integer greater than or equal to the specified number.
map.put("divide", "$divide"); // Returns the result of dividing the first number by the second.
map.put("exp", "$exp"); // Raises e to the specified exponent.
map.put("floor", "$floor"); // Returns the largest integer less than or equal to the specified number.
map.put("ln", "$ln"); // Calculates the natural log of a number.
map.put("log", "$log"); // Calculates the log of a number in the specified base.
map.put("log10", "$log10"); // Calculates the log base 10 of a number.
map.put("mod", "$mod"); // Returns the remainder of the first number divided by the second.
map.put("multiply", "$multiply"); // Multiplies numbers to return the product.
map.put("pow", "$pow"); // Raises a number to the specified exponent.
map.put("sqrt", "$sqrt"); // Calculates the square root.
map.put("subtract", "$subtract"); // Returns the result of subtracting the second value from the first. If the
// two values are numbers, return the difference. If the two values are dates, return the difference in milliseconds.
map.put("trunc", "$trunc"); // Truncates a number to its integer.

map.put("concat", "$concat"); // Concatenates two strings.
map.put("strcasecmp", "$strcasecmp"); // Compares two strings and returns an integer that reflects the comparison.
map.put("substr", "$substr"); // Takes a string and returns portion of that string.
map.put("toLower", "$toLower"); // Converts a string to lowercase.
map.put("toUpper", "$toUpper"); // Converts a string to uppercase.
map.put("strcasecmp", "$strcasecmp"); // Compares two strings and returns an integer that reflects the comparison.

map.put("meta", "$meta"); // Access text search metadata.

map.put("arrayElemAt", "$arrayElemAt"); // Returns the element at the specified array index.
map.put("concatArrays", "$concatArrays"); // Concatenates arrays to return the concatenated array.
map.put("filter", "$filter"); // Selects a subset of the array to return an array with only the elements that
// match the filter condition.
map.put("isArray", "$isArray"); // Determines if the operand is an array. Returns a boolean.
map.put("size", "$size"); // Returns the number of elements in the array.
map.put("slice", "$slice"); // Returns a subset of an array.

map.put("map", "$map"); // Applies a subexpression to each element of an array and returns the array of
// resulting values in order.
map.put("let", "$let"); // Defines variables for use within the scope of a subexpression and returns the result
// of the subexpression.

map.put("literal", "$literal"); // Return a value without parsing.

map.put("dayOfYear", "$dayOfYear"); // Converts a date to a number between 1 and 366.
map.put("dayOfMonth", "$dayOfMonth"); // Converts a date to a number between 1 and 31.
Expand All @@ -52,7 +107,13 @@ public class MethodReferenceNode extends ExpressionNode {
map.put("minute", "$minute"); // Converts a date into a number between 0 and 59.
map.put("second", "$second"); // Converts a date into a number between 0 and 59. May be 60 to account for leap
// seconds.
map.put("millisecond", "$millisecond"); // Returns the millisecond portion of a date as an integer between 0 and
map.put("millisecond", "$millisecond"); // Returns the millisecond portion of a date as an integer between 0 and 999.
map.put("dateToString", "$dateToString"); // Returns the date as a formatted string.

map.put("cond", "$cond"); // A ternary operator that evaluates one expression, and depending on the result,
// returns the value of one of the other two expressions.
map.put("ifNull", "$ifNull"); // Returns either the non-null result of the first expression or the result of the
// second expression if the first expression results in a null result.

FUNCTIONS = Collections.unmodifiableMap(map);
}
Expand All @@ -63,11 +124,8 @@ public class MethodReferenceNode extends ExpressionNode {

/**
* Returns the name of the method.
*
* @return
*/
public String getMethodName() {

String name = getName();
String methodName = name.substring(0, name.indexOf('('));
return FUNCTIONS.get(methodName);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@

/**
* An {@link ExpressionNode} representing an operator.
*
*
* @author Oliver Gierke
* @author Thomas Darimont
*/
Expand All @@ -47,14 +47,18 @@ public class OperatorNode extends ExpressionNode {
map.put("/", "$divide");
map.put("%", "$mod");

map.put("and", "and");
map.put("or", "or");
map.put("!", "not");

OPERATORS = Collections.unmodifiableMap(map);
}

private final Operator operator;

/**
* Creates a new {@link OperatorNode} from the given {@link Operator} and {@link ExpressionState}.
*
*
* @param node must not be {@literal null}.
* @param state must not be {@literal null}.
*/
Expand All @@ -75,44 +79,34 @@ public boolean isMathematicalOperation() {

/**
* Returns whether the operator is unary.
*
* @return
*/
public boolean isUnaryOperator() {
return operator.getRightOperand() == null;
}

/**
* Returns the Mongo expression of the operator.
*
* @return
*/
public String getMongoOperator() {
return OPERATORS.get(operator.getOperatorName());
}

/**
* Returns whether the operator is a unary minus, e.g. -1.
*
* @return
*/
public boolean isUnaryMinus() {
return isUnaryOperator() && operator instanceof OpMinus;
}

/**
* Returns the left operand as {@link ExpressionNode}.
*
* @return
*/
public ExpressionNode getLeft() {
return from(operator.getLeftOperand());
}

/**
* Returns the right operand as {@link ExpressionNode}.
*
* @return
*/
public ExpressionNode getRight() {
return from(operator.getRightOperand());
Expand Down