@ -44,6 +44,8 @@ import com.mongodb.DBObject;
public class ProjectionOperation implements FieldsExposingAggregationOperation {
public class ProjectionOperation implements FieldsExposingAggregationOperation {
private static final List < Projection > NONE = Collections . emptyList ( ) ;
private static final List < Projection > NONE = Collections . emptyList ( ) ;
private static final String EXCLUSION_ERROR = "Exclusion of field %s not allowed. Projections by the mongodb "
+ "aggregation framework only support the exclusion of the %s field!" ;
private final List < Projection > projections ;
private final List < Projection > projections ;
@ -60,7 +62,7 @@ public class ProjectionOperation implements FieldsExposingAggregationOperation {
* @param fields must not be { @literal null } .
* @param fields must not be { @literal null } .
* /
* /
public ProjectionOperation ( Fields fields ) {
public ProjectionOperation ( Fields fields ) {
this ( NONE , ProjectionOperationBuilder . FieldProjection . from ( fields , true ) ) ;
this ( NONE , ProjectionOperationBuilder . FieldProjection . from ( fields ) ) ;
}
}
/ * *
/ * *
@ -117,23 +119,29 @@ public class ProjectionOperation implements FieldsExposingAggregationOperation {
/ * *
/ * *
* Excludes the given fields from the projection .
* Excludes the given fields from the projection .
*
*
* @param fields must not be { @literal null } .
* @param fieldName s must not be { @literal null } .
* @return
* @return
* /
* /
public ProjectionOperation andExclude ( String . . . fields ) {
public ProjectionOperation andExclude ( String . . . fieldNames ) {
List < FieldProjection > excludeProjections = FieldProjection . from ( Fields . fields ( fields ) , false ) ;
for ( String fieldName : fieldNames ) {
Assert . isTrue ( Fields . UNDERSCORE_ID . equals ( fieldName ) ,
String . format ( EXCLUSION_ERROR , fieldName , Fields . UNDERSCORE_ID ) ) ;
}
List < FieldProjection > excludeProjections = FieldProjection . from ( Fields . fields ( fieldNames ) , false ) ;
return new ProjectionOperation ( this . projections , excludeProjections ) ;
return new ProjectionOperation ( this . projections , excludeProjections ) ;
}
}
/ * *
/ * *
* Includes the given fields into the projection .
* Includes the given fields into the projection .
*
*
* @param fields must not be { @literal null } .
* @param fieldName s must not be { @literal null } .
* @return
* @return
* /
* /
public ProjectionOperation andInclude ( String . . . fields ) {
public ProjectionOperation andInclude ( String . . . fieldName s ) {
List < FieldProjection > projections = FieldProjection . from ( Fields . fields ( fields ) , true ) ;
List < FieldProjection > projections = FieldProjection . from ( Fields . fields ( fieldName s ) , true ) ;
return new ProjectionOperation ( this . projections , projections ) ;
return new ProjectionOperation ( this . projections , projections ) ;
}
}
@ -387,31 +395,31 @@ public class ProjectionOperation implements FieldsExposingAggregationOperation {
this . value = value ;
this . value = value ;
}
}
/ * *
* Factory method to easily create { @link FieldProjection } s for the given { @link Fields } . Fields are projected as
* references with their given name . A field { @code foo } will be projected as : { @code foo : 1 } .
*
* @param fields the { @link Fields } to in - or exclude , must not be { @literal null } .
* @return
* /
public static List < ? extends Projection > from ( Fields fields ) {
return from ( fields , null ) ;
}
/ * *
/ * *
* Factory method to easily create { @link FieldProjection } s for the given { @link Fields } .
* Factory method to easily create { @link FieldProjection } s for the given { @link Fields } .
*
*
* @param fields the { @link Fields } to in - or exclude , must not be { @literal null } .
* @param fields the { @link Fields } to in - or exclude , must not be { @literal null } .
* @param include whether to include or exclude the fields .
* @param value to use for the given field .
* @return
* @return
* /
* /
public static List < FieldProjection > from ( Fields fields , boolean include ) {
public static List < FieldProjection > from ( Fields fields , Object valu e) {
Assert . notNull ( fields , "Fields must not be null!" ) ;
Assert . notNull ( fields , "Fields must not be null!" ) ;
List < FieldProjection > projections = new ArrayList < FieldProjection > ( ) ;
List < FieldProjection > projections = new ArrayList < FieldProjection > ( ) ;
for ( Field field : fields ) {
for ( Field field : fields ) {
projections . add ( new FieldProjection ( field , value ) ) ;
if ( ! include ) {
if ( ! Fields . UNDERSCORE_ID . equals ( field . getName ( ) ) ) {
throw new IllegalArgumentException (
String
. format (
"Exclusion of field %s not allowed. Projections by the mongodb aggregation framework only support the exclusion of the %s field!" ,
field . getName ( ) , Fields . UNDERSCORE_ID ) ) ;
}
}
projections . add ( new FieldProjection ( field , include ? null : 0 ) ) ;
}
}
return projections ;
return projections ;
@ -423,13 +431,32 @@ public class ProjectionOperation implements FieldsExposingAggregationOperation {
* /
* /
@Override
@Override
public DBObject toDBObject ( AggregationOperationContext context ) {
public DBObject toDBObject ( AggregationOperationContext context ) {
return new BasicDBObject ( field . getName ( ) , renderFieldValue ( context ) ) ;
if ( value ! = null ) {
return new BasicDBObject ( field . getName ( ) , value ) ;
}
}
private Object renderFieldValue ( AggregationOperationContext context ) {
// implicit reference or explicit include?
if ( value = = null | | Boolean . TRUE . equals ( value ) ) {
// check whether referenced field exists in the context
FieldReference reference = context . getReference ( field . getTarget ( ) ) ;
FieldReference reference = context . getReference ( field . getTarget ( ) ) ;
return new BasicDBObject ( field . getName ( ) , reference . toString ( ) ) ;
if ( field . getName ( ) . equals ( field . getTarget ( ) ) ) {
// render field as included
return 1 ;
}
// render field reference
return reference . toString ( ) ;
} else if ( Boolean . FALSE . equals ( value ) ) {
// render field as excluded
return 0 ;
}
return value ;
}
}
}
}