44
44
public class ProjectionOperation implements FieldsExposingAggregationOperation {
45
45
46
46
private static final List <Projection > NONE = Collections .emptyList ();
47
+ private static final String EXCLUSION_ERROR = "Exclusion of field %s not allowed. Projections by the mongodb "
48
+ + "aggregation framework only support the exclusion of the %s field!" ;
47
49
48
50
private final List <Projection > projections ;
49
51
@@ -60,7 +62,7 @@ public ProjectionOperation() {
60
62
* @param fields must not be {@literal null}.
61
63
*/
62
64
public ProjectionOperation (Fields fields ) {
63
- this (NONE , ProjectionOperationBuilder .FieldProjection .from (fields , true ));
65
+ this (NONE , ProjectionOperationBuilder .FieldProjection .from (fields ));
64
66
}
65
67
66
68
/**
@@ -117,23 +119,29 @@ public ProjectionOperationBuilder and(String name) {
117
119
/**
118
120
* Excludes the given fields from the projection.
119
121
*
120
- * @param fields must not be {@literal null}.
122
+ * @param fieldNames must not be {@literal null}.
121
123
* @return
122
124
*/
123
- public ProjectionOperation andExclude (String ... fields ) {
124
- List <FieldProjection > excludeProjections = FieldProjection .from (Fields .fields (fields ), false );
125
+ public ProjectionOperation andExclude (String ... fieldNames ) {
126
+
127
+ for (String fieldName : fieldNames ) {
128
+ Assert .isTrue (Fields .UNDERSCORE_ID .equals (fieldName ),
129
+ String .format (EXCLUSION_ERROR , fieldName , Fields .UNDERSCORE_ID ));
130
+ }
131
+
132
+ List <FieldProjection > excludeProjections = FieldProjection .from (Fields .fields (fieldNames ), false );
125
133
return new ProjectionOperation (this .projections , excludeProjections );
126
134
}
127
135
128
136
/**
129
137
* Includes the given fields into the projection.
130
138
*
131
- * @param fields must not be {@literal null}.
139
+ * @param fieldNames must not be {@literal null}.
132
140
* @return
133
141
*/
134
- public ProjectionOperation andInclude (String ... fields ) {
142
+ public ProjectionOperation andInclude (String ... fieldNames ) {
135
143
136
- List <FieldProjection > projections = FieldProjection .from (Fields .fields (fields ), true );
144
+ List <FieldProjection > projections = FieldProjection .from (Fields .fields (fieldNames ), true );
137
145
return new ProjectionOperation (this .projections , projections );
138
146
}
139
147
@@ -387,31 +395,31 @@ private FieldProjection(Field field, Object value) {
387
395
this .value = value ;
388
396
}
389
397
398
+ /**
399
+ * Factory method to easily create {@link FieldProjection}s for the given {@link Fields}. Fields are projected as
400
+ * references with their given name. A field {@code foo} will be projected as: {@code foo : 1 } .
401
+ *
402
+ * @param fields the {@link Fields} to in- or exclude, must not be {@literal null}.
403
+ * @return
404
+ */
405
+ public static List <? extends Projection > from (Fields fields ) {
406
+ return from (fields , null );
407
+ }
408
+
390
409
/**
391
410
* Factory method to easily create {@link FieldProjection}s for the given {@link Fields}.
392
411
*
393
412
* @param fields the {@link Fields} to in- or exclude, must not be {@literal null}.
394
- * @param include whether to include or exclude the fields .
413
+ * @param value to use for the given field .
395
414
* @return
396
415
*/
397
- public static List <FieldProjection > from (Fields fields , boolean include ) {
416
+ public static List <FieldProjection > from (Fields fields , Object value ) {
398
417
399
418
Assert .notNull (fields , "Fields must not be null!" );
400
419
List <FieldProjection > projections = new ArrayList <FieldProjection >();
401
420
402
421
for (Field field : fields ) {
403
-
404
- if (!include ) {
405
- if (!Fields .UNDERSCORE_ID .equals (field .getName ())) {
406
- throw new IllegalArgumentException (
407
- String
408
- .format (
409
- "Exclusion of field %s not allowed. Projections by the mongodb aggregation framework only support the exclusion of the %s field!" ,
410
- field .getName (), Fields .UNDERSCORE_ID ));
411
- }
412
- }
413
-
414
- projections .add (new FieldProjection (field , include ? null : 0 ));
422
+ projections .add (new FieldProjection (field , value ));
415
423
}
416
424
417
425
return projections ;
@@ -423,13 +431,32 @@ public static List<FieldProjection> from(Fields fields, boolean include) {
423
431
*/
424
432
@ Override
425
433
public DBObject toDBObject (AggregationOperationContext context ) {
434
+ return new BasicDBObject (field .getName (), renderFieldValue (context ));
435
+ }
436
+
437
+ private Object renderFieldValue (AggregationOperationContext context ) {
438
+
439
+ // implicit reference or explicit include?
440
+ if (value == null || Boolean .TRUE .equals (value )) {
441
+
442
+ // check whether referenced field exists in the context
443
+ FieldReference reference = context .getReference (field .getTarget ());
444
+
445
+ if (field .getName ().equals (field .getTarget ())) {
446
+
447
+ // render field as included
448
+ return 1 ;
449
+ }
450
+
451
+ // render field reference
452
+ return reference .toString ();
453
+ } else if (Boolean .FALSE .equals (value )) {
426
454
427
- if ( value != null ) {
428
- return new BasicDBObject ( field . getName (), value ) ;
455
+ // render field as excluded
456
+ return 0 ;
429
457
}
430
458
431
- FieldReference reference = context .getReference (field .getTarget ());
432
- return new BasicDBObject (field .getName (), reference .toString ());
459
+ return value ;
433
460
}
434
461
}
435
462
0 commit comments