@ -24,7 +24,6 @@ import org.springframework.data.mongodb.core.aggregation.ExposedFields.ExposedFi
@@ -24,7 +24,6 @@ import org.springframework.data.mongodb.core.aggregation.ExposedFields.ExposedFi
import org.springframework.data.mongodb.core.aggregation.ProjectionOperation.ProjectionOperationBuilder.FieldProjection ;
import org.springframework.util.Assert ;
import com.mongodb.BasicDBList ;
import com.mongodb.BasicDBObject ;
import com.mongodb.DBObject ;
@ -235,26 +234,53 @@ public class ProjectionOperation implements FieldsExposingAggregationOperation {
@@ -235,26 +234,53 @@ public class ProjectionOperation implements FieldsExposingAggregationOperation {
}
/ * *
* An { @link ProjectionOperationBuilder } that is used for SpEL expression based projections .
*
* @author Thomas Darimont
* /
public static class ExpressionProjectionOperationBuilder extends Abstract ProjectionOperationBuilder {
public static class ExpressionProjectionOperationBuilder extends ProjectionOperationBuilder {
private final Object [ ] params ;
private final String expression ;
/ * *
* Creates a new { @link ExpressionProjectionOperationBuilder } for the given value , { @link ProjectionOperation } and
* parameters .
*
* @param value must not be { @literal null } .
* @param expression must not be { @literal null } .
* @param operation must not be { @literal null } .
* @param parameters
* /
public ExpressionProjectionOperationBuilder ( Object value , ProjectionOperation operation , Object [ ] parameters ) {
public ExpressionProjectionOperationBuilder ( String expression , ProjectionOperation operation , Object [ ] parameters ) {
super ( value , operation ) ;
super ( expression , operation , null ) ;
this . expression = expression ;
this . params = parameters . clone ( ) ;
}
/ * ( non - Javadoc )
* @see org . springframework . data . mongodb . core . aggregation . ProjectionOperation . ProjectionOperationBuilder # project ( java . lang . String , java . lang . Object [ ] )
* /
@Override
public ProjectionOperationBuilder project ( String operation , final Object . . . values ) {
OperationProjection operationProjection = new OperationProjection ( Fields . field ( value . toString ( ) ) , operation ,
values ) {
@Override
protected List < Object > getOperationArguments ( AggregationOperationContext context ) {
List < Object > result = new ArrayList < Object > ( values . length + 1 ) ;
result . add ( ExpressionProjection . toMongoExpression ( context ,
ExpressionProjectionOperationBuilder . this . expression , ExpressionProjectionOperationBuilder . this . params ) ) ;
result . addAll ( Arrays . asList ( values ) ) ;
return result ;
}
} ;
return new ProjectionOperationBuilder ( value , this . operation . and ( operationProjection ) , operationProjection ) ;
}
/ *
* ( non - Javadoc )
* @see org . springframework . data . mongodb . core . aggregation . ProjectionOperation . AbstractProjectionOperationBuilder # as ( java . lang . String )
@ -303,7 +329,11 @@ public class ProjectionOperation implements FieldsExposingAggregationOperation {
@@ -303,7 +329,11 @@ public class ProjectionOperation implements FieldsExposingAggregationOperation {
* /
@Override
public DBObject toDBObject ( AggregationOperationContext context ) {
return new BasicDBObject ( getExposedField ( ) . getName ( ) , TRANSFORMER . transform ( expression , context , params ) ) ;
return new BasicDBObject ( getExposedField ( ) . getName ( ) , toMongoExpression ( context , expression , params ) ) ;
}
protected static Object toMongoExpression ( AggregationOperationContext context , String expression , Object [ ] params ) {
return TRANSFORMER . transform ( expression , context , params ) ;
}
}
}
@ -320,7 +350,6 @@ public class ProjectionOperation implements FieldsExposingAggregationOperation {
@@ -320,7 +350,6 @@ public class ProjectionOperation implements FieldsExposingAggregationOperation {
private static final String FIELD_REFERENCE_NOT_NULL = "Field reference must not be null!" ;
private final String name ;
private final ProjectionOperation operation ;
private final OperationProjection previousProjection ;
/ * *
@ -335,7 +364,23 @@ public class ProjectionOperation implements FieldsExposingAggregationOperation {
@@ -335,7 +364,23 @@ public class ProjectionOperation implements FieldsExposingAggregationOperation {
super ( name , operation ) ;
this . name = name ;
this . operation = operation ;
this . previousProjection = previousProjection ;
}
/ * *
* Creates a new { @link ProjectionOperationBuilder } for the field with the given value on top of the given
* { @link ProjectionOperation } .
*
* @param value
* @param operation
* @param previousProjection
* /
protected ProjectionOperationBuilder ( Object value , ProjectionOperation operation ,
OperationProjection previousProjection ) {
super ( value , operation ) ;
this . name = null ;
this . previousProjection = previousProjection ;
}
@ -521,8 +566,9 @@ public class ProjectionOperation implements FieldsExposingAggregationOperation {
@@ -521,8 +566,9 @@ public class ProjectionOperation implements FieldsExposingAggregationOperation {
* @return
* /
public ProjectionOperationBuilder project ( String operation , Object . . . values ) {
OperationProjection projectionOperation = new OperationProjection ( Fields . field ( name ) , operation , values ) ;
return new ProjectionOperationBuilder ( name , this . operation . and ( projectionOperation ) , projectionOperation ) ;
OperationProjection operationProjection = new OperationProjection ( Fields . field ( value . toString ( ) ) , operation ,
values ) ;
return new ProjectionOperationBuilder ( value , this . operation . and ( operationProjection ) , operationProjection ) ;
}
/ * *
@ -653,7 +699,7 @@ public class ProjectionOperation implements FieldsExposingAggregationOperation {
@@ -653,7 +699,7 @@ public class ProjectionOperation implements FieldsExposingAggregationOperation {
/ * *
* Creates a new { @link OperationProjection } for the given field .
*
* @param name the name of the field to add the operation projection for , must not be { @literal null } or empty .
* @param field the name of the field to add the operation projection for , must not be { @literal null } or empty .
* @param operation the actual operation key , must not be { @literal null } or empty .
* @param values the values to pass into the operation , must not be { @literal null } .
* /
@ -676,18 +722,15 @@ public class ProjectionOperation implements FieldsExposingAggregationOperation {
@@ -676,18 +722,15 @@ public class ProjectionOperation implements FieldsExposingAggregationOperation {
@Override
public DBObject toDBObject ( AggregationOperationContext context ) {
BasicDBList values = new BasicDBList ( ) ;
values . addAll ( buildReferences ( context ) ) ;
DBObject inner = new BasicDBObject ( "$" + operation , getOperationArguments ( context ) ) ;
DBObject inner = new BasicDBObject ( "$" + operation , values ) ;
return new BasicDBObject ( this . field . getName ( ) , inner ) ;
return new BasicDBObject ( getField ( ) . getName ( ) , inner ) ;
}
private List < Object > buildReference s( AggregationOperationContext context ) {
protected List < Object > getOperationArgument s( AggregationOperationContext context ) {
List < Object > result = new ArrayList < Object > ( values . size ( ) ) ;
result . add ( context . getReference ( field . getTarget ( ) ) . toString ( ) ) ;
result . add ( context . getReference ( getField ( ) . getName ( ) ) . toString ( ) ) ;
for ( Object element : values ) {
result . add ( element instanceof Field ? context . getReference ( ( Field ) element ) . toString ( ) : element ) ;
@ -696,6 +739,15 @@ public class ProjectionOperation implements FieldsExposingAggregationOperation {
@@ -696,6 +739,15 @@ public class ProjectionOperation implements FieldsExposingAggregationOperation {
return result ;
}
/ * *
* Returns the field that holds the { @link OperationProjection } .
*
* @return
* /
protected Field getField ( ) {
return field ;
}
/ * *
* Creates a new instance of this { @link OperationProjection } with the given alias .
*
@ -703,7 +755,27 @@ public class ProjectionOperation implements FieldsExposingAggregationOperation {
@@ -703,7 +755,27 @@ public class ProjectionOperation implements FieldsExposingAggregationOperation {
* @return
* /
public OperationProjection withAlias ( String alias ) {
return new OperationProjection ( Fields . field ( alias , this . field . getName ( ) ) , operation , values . toArray ( ) ) ;
final Field aliasedField = Fields . field ( alias , this . field . getName ( ) ) ;
return new OperationProjection ( aliasedField , operation , values . toArray ( ) ) {
/ * ( non - Javadoc )
* @see org . springframework . data . mongodb . core . aggregation . ProjectionOperation . ProjectionOperationBuilder . OperationProjection # getField ( )
* /
@Override
protected Field getField ( ) {
return aliasedField ;
}
@Override
protected List < Object > getOperationArguments ( AggregationOperationContext context ) {
// We have to make sure that we use the arguments from the "previous" OperationProjection that we replace
// with this new instance.
return OperationProjection . this . getOperationArguments ( context ) ;
}
} ;
}
}
@ -735,6 +807,96 @@ public class ProjectionOperation implements FieldsExposingAggregationOperation {
@@ -735,6 +807,96 @@ public class ProjectionOperation implements FieldsExposingAggregationOperation {
return new BasicDBObject ( name , nestedObject ) ;
}
}
/ * *
* Extracts the minute from a date expression .
*
* @return
* /
public ProjectionOperationBuilder extractMinute ( ) {
return project ( "minute" ) ;
}
/ * *
* Extracts the hour from a date expression .
*
* @return
* /
public ProjectionOperationBuilder extractHour ( ) {
return project ( "hour" ) ;
}
/ * *
* Extracts the second from a date expression .
*
* @return
* /
public ProjectionOperationBuilder extractSecond ( ) {
return project ( "second" ) ;
}
/ * *
* Extracts the millisecond from a date expression .
*
* @return
* /
public ProjectionOperationBuilder extractMillisecond ( ) {
return project ( "millisecond" ) ;
}
/ * *
* Extracts the year from a date expression .
*
* @return
* /
public ProjectionOperationBuilder extractYear ( ) {
return project ( "year" ) ;
}
/ * *
* Extracts the month from a date expression .
*
* @return
* /
public ProjectionOperationBuilder extractMonth ( ) {
return project ( "month" ) ;
}
/ * *
* Extracts the week from a date expression .
*
* @return
* /
public ProjectionOperationBuilder extractWeek ( ) {
return project ( "week" ) ;
}
/ * *
* Extracts the dayOfYear from a date expression .
*
* @return
* /
public ProjectionOperationBuilder extractDayOfYear ( ) {
return project ( "dayOfYear" ) ;
}
/ * *
* Extracts the dayOfMonth from a date expression .
*
* @return
* /
public ProjectionOperationBuilder extractDayOfMonth ( ) {
return project ( "dayOfMonth" ) ;
}
/ * *
* Extracts the dayOfWeek from a date expression .
*
* @return
* /
public ProjectionOperationBuilder extractDayOfWeek ( ) {
return project ( "dayOfWeek" ) ;
}
}
/ * *
@ -775,5 +937,4 @@ public class ProjectionOperation implements FieldsExposingAggregationOperation {
@@ -775,5 +937,4 @@ public class ProjectionOperation implements FieldsExposingAggregationOperation {
* /
public abstract DBObject toDBObject ( AggregationOperationContext context ) ;
}
}