View Javadoc
1   /*
2    * #%L
3    * MapReduce.java - mongodb-async-driver - Allanbank Consulting, Inc.
4    * %%
5    * Copyright (C) 2011 - 2014 Allanbank Consulting, Inc.
6    * %%
7    * Licensed under the Apache License, Version 2.0 (the "License");
8    * you may not use this file except in compliance with the License.
9    * You may obtain a copy of the License at
10   * 
11   *      http://www.apache.org/licenses/LICENSE-2.0
12   * 
13   * Unless required by applicable law or agreed to in writing, software
14   * distributed under the License is distributed on an "AS IS" BASIS,
15   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16   * See the License for the specific language governing permissions and
17   * limitations under the License.
18   * #L%
19   */
20  
21  package com.allanbank.mongodb.builder;
22  
23  import static com.allanbank.mongodb.util.Assertions.assertNotNull;
24  import static com.allanbank.mongodb.util.Assertions.assertThat;
25  
26  import java.util.concurrent.TimeUnit;
27  
28  import com.allanbank.mongodb.MongoCollection;
29  import com.allanbank.mongodb.ReadPreference;
30  import com.allanbank.mongodb.Version;
31  import com.allanbank.mongodb.bson.Document;
32  import com.allanbank.mongodb.bson.DocumentAssignable;
33  import com.allanbank.mongodb.bson.builder.BuilderFactory;
34  import com.allanbank.mongodb.bson.builder.DocumentBuilder;
35  import com.allanbank.mongodb.bson.element.IntegerElement;
36  
37  /**
38   * Represents the state of a single {@link MongoCollection#mapReduce} command.
39   * Objects of this class are created using the nested {@link Builder}.
40   * 
41   * @api.yes This class is part of the driver's API. Public and protected members
42   *          will be deprecated for at least 1 non-bugfix release (version
43   *          numbers are <major>.<minor>.<bugfix>) before being
44   *          removed or modified.
45   * @copyright 2011-2013, Allanbank Consulting, Inc., All Rights Reserved
46   */
47  public class MapReduce {
48      /**
49       * The first version of MongoDB to support the {@code mapreduce} command
50       * with the ability to limit the execution time on the server.
51       */
52      public static final Version MAX_TIMEOUT_VERSION = Find.MAX_TIMEOUT_VERSION;
53  
54      /**
55       * Creates a new builder for a {@link MapReduce}.
56       * 
57       * @return The builder to construct a {@link MapReduce}.
58       */
59      public static Builder builder() {
60          return new Builder();
61      }
62  
63      /**
64       * The finalize function to apply to the final results of the reduce
65       * function.
66       */
67      private final String myFinalizeFunction;
68  
69      /**
70       * If true limits the translation of the documents to an from
71       * BSON/JavaScript.
72       */
73      private final boolean myJsMode;
74  
75      /**
76       * If true then the temporary collections created during the map/reduce
77       * should not be dropped.
78       */
79      private final boolean myKeepTemp;
80  
81      /** Limits the number of objects to be used as input to the map/reduce. */
82      private final int myLimit;
83  
84      /** The map functions to apply to each selected document. */
85      private final String myMapFunction;
86  
87      /** The maximum amount of time to allow the command to run. */
88      private final long myMaximumTimeMilliseconds;
89  
90      /**
91       * The name of the output database if the output type is One of
92       * {@link OutputType#REPLACE}, {@link OutputType#MERGE}, or
93       * {@link OutputType#REDUCE}.
94       */
95      private final String myOutputDatabase;
96  
97      /**
98       * The name of the output collection if the output type is One of
99       * {@link OutputType#REPLACE}, {@link OutputType#MERGE}, or
100      * {@link OutputType#REDUCE}.
101      */
102     private final String myOutputName;
103 
104     /** The handling for the output of the map/reduce. */
105     private final OutputType myOutputType;
106 
107     /** The query to select the document to run the map/reduce against. */
108     private final Document myQuery;
109 
110     /** The read preference to use. */
111     private final ReadPreference myReadPreference;
112 
113     /** The reduce function to apply to the emitted output of the map function. */
114     private final String myReduceFunction;
115 
116     /** The scoped values to expose to the map/reduce/finalize functions. */
117     private final Document myScope;
118 
119     /**
120      * The sort to apply to the input objects. Useful for optimization, like
121      * sorting by the emit key for fewer reduces.
122      */
123     private final Document mySort;
124 
125     /** If true emits progress messages in the server logs. */
126     private final boolean myVerbose;
127 
128     /**
129      * Create a new MapReduce.
130      * 
131      * @param builder
132      *            The builder to copy state from.
133      */
134     protected MapReduce(final Builder builder) {
135         assertNotNull(builder.myMapFunction,
136                 "A mapReduce must have a map function.");
137         assertNotNull(builder.myReduceFunction,
138                 "A mapReduce must have a reduce function.");
139         assertThat(
140                 (builder.myOutputType == OutputType.INLINE)
141                         || ((builder.myOutputName != null) && !builder.myOutputName
142                                 .isEmpty()),
143                 "A mapReduce output type must be INLINE or an output collection must be specified.");
144 
145         myMapFunction = builder.myMapFunction;
146         myReduceFunction = builder.myReduceFunction;
147         myFinalizeFunction = builder.myFinalizeFunction;
148         myQuery = builder.myQuery;
149         mySort = builder.mySort;
150         myScope = builder.myScope;
151         myLimit = builder.myLimit;
152         myOutputName = builder.myOutputName;
153         myOutputDatabase = builder.myOutputDatabase;
154         myOutputType = builder.myOutputType;
155         myKeepTemp = builder.myKeepTemp;
156         myJsMode = builder.myJsMode;
157         myVerbose = builder.myVerbose;
158         myReadPreference = builder.myReadPreference;
159         myMaximumTimeMilliseconds = builder.myMaximumTimeMilliseconds;
160     }
161 
162     /**
163      * Returns the finalize function to apply to the final results of the reduce
164      * function.
165      * 
166      * @return The finalize function to apply to the final results of the reduce
167      *         function.
168      */
169     public String getFinalizeFunction() {
170         return myFinalizeFunction;
171     }
172 
173     /**
174      * Returns the limit for the number of objects to be used as input to the
175      * map/reduce.
176      * 
177      * @return The limit for the number of objects to be used as input to the
178      *         map/reduce.
179      */
180     public int getLimit() {
181         return myLimit;
182     }
183 
184     /**
185      * Returns the map functions to apply to each selected document.
186      * 
187      * @return The map functions to apply to each selected document.
188      */
189     public String getMapFunction() {
190         return myMapFunction;
191     }
192 
193     /**
194      * Returns the maximum amount of time to allow the command to run on the
195      * Server before it is aborted.
196      * 
197      * @return The maximum amount of time to allow the command to run on the
198      *         Server before it is aborted.
199      * 
200      * @since MongoDB 2.6
201      */
202     public long getMaximumTimeMilliseconds() {
203         return myMaximumTimeMilliseconds;
204     }
205 
206     /**
207      * Returns the name of the output database if the output type is One of
208      * {@link OutputType#REPLACE}, {@link OutputType#MERGE}, or
209      * {@link OutputType#REDUCE}.
210      * 
211      * @return The name of the output database if the output type is One of
212      *         {@link OutputType#REPLACE}, {@link OutputType#MERGE}, or
213      *         {@link OutputType#REDUCE}.
214      */
215     public String getOutputDatabase() {
216         return myOutputDatabase;
217     }
218 
219     /**
220      * Returns the name of the output collection if the output type is One of
221      * {@link OutputType#REPLACE}, {@link OutputType#MERGE}, or
222      * {@link OutputType#REDUCE}.
223      * 
224      * @return The name of the output collection if the output type is One of
225      *         {@link OutputType#REPLACE}, {@link OutputType#MERGE}, or
226      *         {@link OutputType#REDUCE}.
227      */
228     public String getOutputName() {
229         return myOutputName;
230     }
231 
232     /**
233      * Returns the handling for the output of the map/reduce.
234      * 
235      * @return The handling for the output of the map/reduce.
236      */
237     public OutputType getOutputType() {
238         return myOutputType;
239     }
240 
241     /**
242      * Returns the query to select the documents to run the map/reduce against.
243      * 
244      * @return The query to select the documents to run the map/reduce against.
245      */
246     public Document getQuery() {
247         return myQuery;
248     }
249 
250     /**
251      * Returns the {@link ReadPreference} specifying which servers may be used
252      * to execute the {@link MapReduce} command.
253      * <p>
254      * If <code>null</code> then the {@link MongoCollection} instance's
255      * {@link ReadPreference} will be used.
256      * </p>
257      * <p>
258      * <b>NOTE: </b> Passing of read preferences to a {@code mongos} does not
259      * work in a sharded configuration. The query will always be run on the
260      * primary members of all shards.
261      * </p>
262      * 
263      * @return The read preference to use.
264      * 
265      * @see MongoCollection#getReadPreference()
266      */
267     public ReadPreference getReadPreference() {
268         return myReadPreference;
269     }
270 
271     /**
272      * Returns the reduce function to apply to the emitted output of the map
273      * function.
274      * 
275      * @return The reduce function to apply to the emitted output of the map
276      *         function.
277      */
278     public String getReduceFunction() {
279         return myReduceFunction;
280     }
281 
282     /**
283      * Returns the scoped values to expose to the map/reduce/finalize functions.
284      * 
285      * @return The scoped values to expose to the map/reduce/finalize functions.
286      */
287     public Document getScope() {
288         return myScope;
289     }
290 
291     /**
292      * Returns the sort to apply to the input objects. Useful for optimization,
293      * like sorting by the emit key for fewer reduces.
294      * 
295      * @return The sort to apply to the input objects. Useful for optimization,
296      *         like sorting by the emit key for fewer reduces.
297      */
298     public Document getSort() {
299         return mySort;
300     }
301 
302     /**
303      * Returns true to limit the translation of the documents to an from
304      * BSON/JavaScript.
305      * 
306      * @return True to limit the translation of the documents to an from
307      *         BSON/JavaScript.
308      */
309     public boolean isJsMode() {
310         return myJsMode;
311     }
312 
313     /**
314      * Returns true to drop the temporary collections created during the
315      * map/reduce.
316      * 
317      * @return True to drop the temporary collections created during the
318      *         map/reduce.
319      */
320     public boolean isKeepTemp() {
321         return myKeepTemp;
322     }
323 
324     /**
325      * Returns true to emit progress messages in the server logs.
326      * 
327      * @return True to emit progress messages in the server logs.
328      */
329     public boolean isVerbose() {
330         return myVerbose;
331     }
332 
333     /**
334      * Helper for creating immutable {@link MapReduce} commands.
335      * 
336      * @api.yes This class is part of the driver's API. Public and protected
337      *          members will be deprecated for at least 1 non-bugfix release
338      *          (version numbers are &lt;major&gt;.&lt;minor&gt;.&lt;bugfix&gt;)
339      *          before being removed or modified.
340      * @copyright 2011-2013, Allanbank Consulting, Inc., All Rights Reserved
341      */
342     public static class Builder {
343         /**
344          * The finalize function to apply to the final results of the reduce
345          * function.
346          */
347         protected String myFinalizeFunction = null;
348 
349         /**
350          * If true limits the translation of the documents to an from
351          * BSON/JavaScript.
352          */
353         protected boolean myJsMode = false;
354 
355         /**
356          * If true then the temporary collections created during the map/reduce
357          * should not be dropped.
358          */
359         protected boolean myKeepTemp = false;
360 
361         /** Limits the number of objects to be used as input to the map/reduce. */
362         protected int myLimit = 0;
363 
364         /** The map functions to apply to each selected document. */
365         protected String myMapFunction = null;
366 
367         /** The maximum amount of time to allow the command to run. */
368         protected long myMaximumTimeMilliseconds;
369 
370         /**
371          * The name of the output database if the output type is One of
372          * {@link OutputType#REPLACE}, {@link OutputType#MERGE}, or
373          * {@link OutputType#REDUCE}.
374          */
375         protected String myOutputDatabase = null;
376 
377         /**
378          * The name of the output collection if the output type is One of
379          * {@link OutputType#REPLACE}, {@link OutputType#MERGE}, or
380          * {@link OutputType#REDUCE}.
381          */
382         protected String myOutputName = null;
383 
384         /** The handling for the output of the map/reduce. */
385         protected OutputType myOutputType = OutputType.INLINE;
386 
387         /** The query to select the document to run the map/reduce against. */
388         protected Document myQuery = null;
389 
390         /** The read preference to use. */
391         protected ReadPreference myReadPreference = null;
392 
393         /**
394          * The reduce function to apply to the emitted output of the map
395          * function.
396          */
397         protected String myReduceFunction = null;
398 
399         /** The scoped values to expose to the map/reduce/finalize functions. */
400         protected Document myScope = null;
401 
402         /**
403          * The sort to apply to the input objects. Useful for optimization, like
404          * sorting by the emit key for fewer reduces.
405          */
406         protected Document mySort = null;
407 
408         /** If true emits progress messages in the server logs. */
409         protected boolean myVerbose = false;
410 
411         /**
412          * Creates a new Builder.
413          */
414         public Builder() {
415             reset();
416         }
417 
418         /**
419          * Constructs a new {@link FindAndModify} object from the state of the
420          * builder.
421          * 
422          * @return The new {@link FindAndModify} object.
423          */
424         public MapReduce build() {
425             return new MapReduce(this);
426         }
427 
428         /**
429          * Sets the finalize function to apply to the final results of the
430          * reduce function.
431          * <p>
432          * This method delegates to {@link #setFinalizeFunction(String)}.
433          * </p>
434          * 
435          * @param finalize
436          *            The finalize function to apply to the final results of the
437          *            reduce function.
438          * @return This builder for chaining method calls.
439          */
440         public Builder finalize(final String finalize) {
441             return setFinalizeFunction(finalize);
442         }
443 
444         /**
445          * Sets to true to limit the translation of the documents to an from
446          * BSON/JavaScript.
447          * <p>
448          * This method delegates to {@link #setJsMode(boolean) setJsMode(true)}.
449          * </p>
450          * 
451          * @return This builder for chaining method calls.
452          */
453         public Builder jsMode() {
454             return setJsMode(true);
455         }
456 
457         /**
458          * Sets to true to limit the translation of the documents to an from
459          * BSON/JavaScript.
460          * <p>
461          * This method delegates to {@link #setJsMode(boolean)}.
462          * </p>
463          * 
464          * @param jsMode
465          *            True to limit the translation of the documents to an from
466          *            BSON/JavaScript.
467          * @return This builder for chaining method calls.
468          */
469         public Builder jsMode(final boolean jsMode) {
470             return setJsMode(jsMode);
471         }
472 
473         /**
474          * Sets to true to drop the temporary collections created during the
475          * map/reduce.
476          * <p>
477          * This method delegates to {@link #setKeepTemp(boolean)
478          * setKeepTemp(true)}.
479          * </p>
480          * 
481          * @return This builder for chaining method calls.
482          */
483         public Builder keepTemp() {
484             return setKeepTemp(true);
485         }
486 
487         /**
488          * Sets to true to drop the temporary collections created during the
489          * map/reduce.
490          * <p>
491          * This method delegates to {@link #keepTemp(boolean)}.
492          * </p>
493          * 
494          * @param keepTemp
495          *            True to drop the temporary collections created during the
496          *            map/reduce.
497          * @return This builder for chaining method calls.
498          */
499         public Builder keepTemp(final boolean keepTemp) {
500             return setKeepTemp(keepTemp);
501         }
502 
503         /**
504          * Sets the limit for the number of objects to be used as input to the
505          * map/reduce.
506          * <p>
507          * This method delegates to {@link #setLimit(int)}.
508          * </p>
509          * 
510          * @param limit
511          *            The limit for the number of objects to be used as input to
512          *            the map/reduce.
513          * @return This builder for chaining method calls.
514          */
515         public Builder limit(final int limit) {
516             return setLimit(limit);
517         }
518 
519         /**
520          * Sets the map functions to apply to each selected document.
521          * <p>
522          * This method delegates to {@link #setMapFunction(String)}.
523          * </p>
524          * 
525          * @param map
526          *            The map functions to apply to each selected document.
527          * @return This builder for chaining method calls.
528          */
529         public Builder map(final String map) {
530             return setMapFunction(map);
531         }
532 
533         /**
534          * Sets the maximum number of milliseconds to allow the command to run
535          * before aborting the request on the server.
536          * <p>
537          * This method equivalent to {@link #setMaximumTimeMilliseconds(long)
538          * setMaximumTimeMilliseconds(timeLimitUnits.toMillis(timeLimit)}.
539          * </p>
540          * 
541          * @param timeLimit
542          *            The new maximum amount of time to allow the command to
543          *            run.
544          * @param timeLimitUnits
545          *            The units for the maximum amount of time to allow the
546          *            command to run.
547          * 
548          * @return This {@link Builder} for method call chaining.
549          * 
550          * @since MongoDB 2.6
551          */
552         public Builder maximumTime(final long timeLimit,
553                 final TimeUnit timeLimitUnits) {
554             return setMaximumTimeMilliseconds(timeLimitUnits
555                     .toMillis(timeLimit));
556         }
557 
558         /**
559          * Sets the name of the output database if the output type is One of
560          * {@link OutputType#REPLACE}, {@link OutputType#MERGE}, or
561          * {@link OutputType#REDUCE}.
562          * <p>
563          * This method delegates to {@link #setOutputDatabase(String)}.
564          * </p>
565          * 
566          * @param outputDatabase
567          *            The name of the output database if the output type is One
568          *            of {@link OutputType#REPLACE}, {@link OutputType#MERGE},
569          *            or {@link OutputType#REDUCE}.
570          * @return This builder for chaining method calls.
571          */
572         public Builder outputDatabase(final String outputDatabase) {
573             return setOutputDatabase(outputDatabase);
574         }
575 
576         /**
577          * Sets the name of the output collection if the output type is One of
578          * {@link OutputType#REPLACE}, {@link OutputType#MERGE}, or
579          * {@link OutputType#REDUCE}.
580          * <p>
581          * This method delegates to {@link #setOutputName(String)}.
582          * </p>
583          * 
584          * @param outputName
585          *            The name of the output collection if the output type is
586          *            One of {@link OutputType#REPLACE},
587          *            {@link OutputType#MERGE}, or {@link OutputType#REDUCE}.
588          * @return This builder for chaining method calls.
589          */
590         public Builder outputName(final String outputName) {
591             return setOutputName(outputName);
592         }
593 
594         /**
595          * Sets the handling for the output of the map/reduce.
596          * <p>
597          * This method delegates to {@link #setOutputType}.
598          * </p>
599          * 
600          * @param outputType
601          *            The handling for the output of the map/reduce.
602          * @return This builder for chaining method calls.
603          */
604         public Builder outputType(final OutputType outputType) {
605             return setOutputType(outputType);
606         }
607 
608         /**
609          * Sets the query to select the documents to run the map/reduce against.
610          * <p>
611          * This method delegates to {@link #setQuery(DocumentAssignable)}.
612          * </p>
613          * 
614          * @param query
615          *            The query to select the documents to run the map/reduce
616          *            against.
617          * @return This builder for chaining method calls.
618          */
619         public Builder query(final DocumentAssignable query) {
620             return setQuery(query);
621         }
622 
623         /**
624          * Sets the {@link ReadPreference} specifying which servers may be used
625          * to execute the {@link MapReduce} command.
626          * <p>
627          * If not set or set to <code>null</code> then the
628          * {@link MongoCollection} instance's {@link ReadPreference} will be
629          * used.
630          * </p>
631          * <p>
632          * This method delegates to {@link #setReadPreference(ReadPreference)}.
633          * </p>
634          * 
635          * @param readPreference
636          *            The read preferences specifying which servers may be used.
637          * @return This builder for chaining method calls.
638          * 
639          * @see MongoCollection#getReadPreference()
640          */
641         public Builder readPreference(final ReadPreference readPreference) {
642             return setReadPreference(readPreference);
643         }
644 
645         /**
646          * Sets the reduce function to apply to the emitted output of the map
647          * function.
648          * <p>
649          * This method delegates to {@link #setReduceFunction(String)}.
650          * </p>
651          * 
652          * @param reduce
653          *            The reduce function to apply to the emitted output of the
654          *            map function.
655          * @return This builder for chaining method calls.
656          */
657         public Builder reduce(final String reduce) {
658             return setReduceFunction(reduce);
659         }
660 
661         /**
662          * Resets the builder back to its initial state.
663          * 
664          * @return This {@link Builder} for method call chaining.
665          */
666         public Builder reset() {
667             myFinalizeFunction = null;
668             myJsMode = false;
669             myKeepTemp = false;
670             myLimit = 0;
671             myMapFunction = null;
672             myMaximumTimeMilliseconds = 0;
673             myOutputDatabase = null;
674             myOutputName = null;
675             myOutputType = OutputType.INLINE;
676             myQuery = null;
677             myReadPreference = null;
678             myReduceFunction = null;
679             myScope = null;
680             mySort = null;
681             myVerbose = false;
682 
683             return this;
684         }
685 
686         /**
687          * Sets the scoped values to expose to the map/reduce/finalize
688          * functions.
689          * <p>
690          * This method delegates to {@link #setScope(DocumentAssignable)}.
691          * </p>
692          * 
693          * @param scope
694          *            The scoped values to expose to the map/reduce/finalize
695          *            functions.
696          * @return This builder for chaining method calls.
697          */
698         public Builder scope(final DocumentAssignable scope) {
699             return setScope(scope);
700         }
701 
702         /**
703          * Sets the finalize function to apply to the final results of the
704          * reduce function.
705          * 
706          * @param finalize
707          *            The finalize function to apply to the final results of the
708          *            reduce function.
709          * @return This builder for chaining method calls.
710          */
711         public Builder setFinalizeFunction(final String finalize) {
712             myFinalizeFunction = finalize;
713             return this;
714         }
715 
716         /**
717          * Sets to true to limit the translation of the documents to an from
718          * BSON/JavaScript.
719          * 
720          * @param jsMode
721          *            True to limit the translation of the documents to an from
722          *            BSON/JavaScript.
723          * @return This builder for chaining method calls.
724          */
725         public Builder setJsMode(final boolean jsMode) {
726             myJsMode = jsMode;
727             return this;
728         }
729 
730         /**
731          * Sets to true to drop the temporary collections created during the
732          * map/reduce.
733          * 
734          * @param keepTemp
735          *            True to drop the temporary collections created during the
736          *            map/reduce.
737          * @return This builder for chaining method calls.
738          */
739         public Builder setKeepTemp(final boolean keepTemp) {
740             myKeepTemp = keepTemp;
741             return this;
742         }
743 
744         /**
745          * Sets the limit for the number of objects to be used as input to the
746          * map/reduce.
747          * 
748          * @param limit
749          *            The limit for the number of objects to be used as input to
750          *            the map/reduce.
751          * @return This builder for chaining method calls.
752          */
753         public Builder setLimit(final int limit) {
754             myLimit = limit;
755             return this;
756         }
757 
758         /**
759          * Sets the map functions to apply to each selected document.
760          * 
761          * @param map
762          *            The map functions to apply to each selected document.
763          * @return This builder for chaining method calls.
764          */
765         public Builder setMapFunction(final String map) {
766             myMapFunction = map;
767             return this;
768         }
769 
770         /**
771          * Sets the maximum number of milliseconds to allow the command to run
772          * before aborting the request on the server.
773          * 
774          * @param maximumTimeMilliseconds
775          *            The new maximum number of milliseconds to allow the
776          *            command to run.
777          * @return This {@link Builder} for method call chaining.
778          * 
779          * @since MongoDB 2.6
780          */
781         public Builder setMaximumTimeMilliseconds(
782                 final long maximumTimeMilliseconds) {
783             myMaximumTimeMilliseconds = maximumTimeMilliseconds;
784             return this;
785         }
786 
787         /**
788          * Sets the name of the output database if the output type is One of
789          * {@link OutputType#REPLACE}, {@link OutputType#MERGE}, or
790          * {@link OutputType#REDUCE}.
791          * 
792          * @param outputDatabase
793          *            The name of the output database if the output type is One
794          *            of {@link OutputType#REPLACE}, {@link OutputType#MERGE},
795          *            or {@link OutputType#REDUCE}.
796          * @return This builder for chaining method calls.
797          */
798         public Builder setOutputDatabase(final String outputDatabase) {
799             myOutputDatabase = outputDatabase;
800             return this;
801         }
802 
803         /**
804          * Sets the name of the output collection if the output type is One of
805          * {@link OutputType#REPLACE}, {@link OutputType#MERGE}, or
806          * {@link OutputType#REDUCE}.
807          * 
808          * @param outputName
809          *            The name of the output collection if the output type is
810          *            One of {@link OutputType#REPLACE},
811          *            {@link OutputType#MERGE}, or {@link OutputType#REDUCE}.
812          * @return This builder for chaining method calls.
813          */
814         public Builder setOutputName(final String outputName) {
815             myOutputName = outputName;
816             return this;
817         }
818 
819         /**
820          * Sets the handling for the output of the map/reduce.
821          * 
822          * @param outputType
823          *            The handling for the output of the map/reduce.
824          * @return This builder for chaining method calls.
825          */
826         public Builder setOutputType(final OutputType outputType) {
827             myOutputType = outputType;
828             return this;
829         }
830 
831         /**
832          * Sets the query to select the documents to run the map/reduce against.
833          * 
834          * @param query
835          *            The query to select the documents to run the map/reduce
836          *            against.
837          * @return This builder for chaining method calls.
838          */
839         public Builder setQuery(final DocumentAssignable query) {
840             myQuery = query.asDocument();
841             return this;
842         }
843 
844         /**
845          * Sets the {@link ReadPreference} specifying which servers may be used
846          * to execute the {@link MapReduce} command.
847          * <p>
848          * If not set or set to <code>null</code> then the
849          * {@link MongoCollection} instance's {@link ReadPreference} will be
850          * used.
851          * </p>
852          * 
853          * @param readPreference
854          *            The read preferences specifying which servers may be used.
855          * @return This builder for chaining method calls.
856          * 
857          * @see MongoCollection#getReadPreference()
858          */
859         public Builder setReadPreference(final ReadPreference readPreference) {
860             myReadPreference = readPreference;
861             return this;
862         }
863 
864         /**
865          * Sets the reduce function to apply to the emitted output of the map
866          * function.
867          * 
868          * @param reduce
869          *            The reduce function to apply to the emitted output of the
870          *            map function.
871          * @return This builder for chaining method calls.
872          */
873         public Builder setReduceFunction(final String reduce) {
874             myReduceFunction = reduce;
875             return this;
876         }
877 
878         /**
879          * Sets the scoped values to expose to the map/reduce/finalize
880          * functions.
881          * 
882          * @param scope
883          *            The scoped values to expose to the map/reduce/finalize
884          *            functions.
885          * @return This builder for chaining method calls.
886          */
887         public Builder setScope(final DocumentAssignable scope) {
888             myScope = scope.asDocument();
889             return this;
890         }
891 
892         /**
893          * Sets the sort to apply to the input objects. Useful for optimization,
894          * like sorting by the emit key for fewer reduces.
895          * 
896          * @param sort
897          *            The sort to apply to the input objects. Useful for
898          *            optimization, like sorting by the emit key for fewer
899          *            reduces.
900          * @return This builder for chaining method calls.
901          */
902         public Builder setSort(final DocumentAssignable sort) {
903             mySort = sort.asDocument();
904             return this;
905         }
906 
907         /**
908          * Sets the sort to apply to the input objects. Useful for optimization,
909          * like sorting by the emit key for fewer reduces.
910          * <p>
911          * This method is intended to be used with the {@link Sort} class's
912          * static methods: <blockquote>
913          * 
914          * <pre>
915          * <code>
916          * import static {@link Sort#asc(String) com.allanbank.mongodb.builder.Sort.asc};
917          * import static {@link Sort#desc(String) com.allanbank.mongodb.builder.Sort.desc};
918          * 
919          * MapReduce.Builder builder = new Find.Builder();
920          * 
921          * builder.setSort( asc("f"), desc("g") );
922          * ...
923          * </code>
924          * </pre>
925          * 
926          * </blockquote>
927          * 
928          * @param sortFields
929          *            The sort to apply to the input objects. Useful for
930          *            optimization, like sorting by the emit key for fewer
931          *            reduces.
932          * @return This builder for chaining method calls.
933          */
934         public Builder setSort(final IntegerElement... sortFields) {
935             final DocumentBuilder builder = BuilderFactory.start();
936             for (final IntegerElement sortField : sortFields) {
937                 builder.add(sortField);
938             }
939             mySort = builder.build();
940             return this;
941         }
942 
943         /**
944          * Sets to true to emit progress messages in the server logs.
945          * 
946          * @param verbose
947          *            True to emit progress messages in the server logs.
948          * @return This builder for chaining method calls.
949          */
950         public Builder setVerbose(final boolean verbose) {
951             myVerbose = verbose;
952             return this;
953         }
954 
955         /**
956          * Sets the sort to apply to the input objects. Useful for optimization,
957          * like sorting by the emit key for fewer reduces.
958          * <p>
959          * This method delegates to {@link #setSort(DocumentAssignable)}.
960          * </p>
961          * 
962          * @param sort
963          *            The sort to apply to the input objects. Useful for
964          *            optimization, like sorting by the emit key for fewer
965          *            reduces.
966          * @return This builder for chaining method calls.
967          */
968         public Builder sort(final DocumentAssignable sort) {
969             return setSort(sort);
970         }
971 
972         /**
973          * Sets the sort to apply to the input objects. Useful for optimization,
974          * like sorting by the emit key for fewer reduces.
975          * <p>
976          * This method delegates to {@link #setSort(IntegerElement...)}.
977          * </p>
978          * <p>
979          * This method is intended to be used with the {@link Sort} class's
980          * static methods: <blockquote>
981          * 
982          * <pre>
983          * <code>
984          * import static {@link Sort#asc(String) com.allanbank.mongodb.builder.Sort.asc};
985          * import static {@link Sort#desc(String) com.allanbank.mongodb.builder.Sort.desc};
986          * 
987          * MapReduce.Builder builder = new Find.Builder();
988          * 
989          * builder.setSort( asc("f"), desc("g") );
990          * ...
991          * </code>
992          * </pre>
993          * 
994          * </blockquote>
995          * 
996          * @param sortFields
997          *            The sort to apply to the input objects. Useful for
998          *            optimization, like sorting by the emit key for fewer
999          *            reduces.
1000          * @return This builder for chaining method calls.
1001          */
1002         public Builder sort(final IntegerElement... sortFields) {
1003             return setSort(sortFields);
1004         }
1005 
1006         /**
1007          * Sets to true to emit progress messages in the server logs.
1008          * <p>
1009          * This method delegates to {@link #setVerbose(boolean)
1010          * setVerbose(true)}.
1011          * </p>
1012          * 
1013          * @return This builder for chaining method calls.
1014          */
1015         public Builder verbose() {
1016             return setVerbose(true);
1017         }
1018 
1019         /**
1020          * Sets to true to emit progress messages in the server logs.
1021          * <p>
1022          * This method delegates to {@link #setVerbose(boolean)}.
1023          * </p>
1024          * 
1025          * @param verbose
1026          *            True to emit progress messages in the server logs.
1027          * @return This builder for chaining method calls.
1028          */
1029         public Builder verbose(final boolean verbose) {
1030             return setVerbose(verbose);
1031         }
1032     }
1033 
1034     /**
1035      * Enumeration of the possible output types.
1036      * 
1037      * @api.yes This enumeration is part of the driver's API. Public and
1038      *          protected members will be deprecated for at least 1 non-bugfix
1039      *          release (version numbers are
1040      *          &lt;major&gt;.&lt;minor&gt;.&lt;bugfix&gt;) before being removed
1041      *          or modified.
1042      * @copyright 2011-2013, Allanbank Consulting, Inc., All Rights Reserved
1043      */
1044     public enum OutputType {
1045         /** Returns the results inline to the reply to the map/reduce command. */
1046         INLINE,
1047 
1048         /**
1049          * Merges the results of the output collections and the map/reduce
1050          * results.
1051          */
1052         MERGE,
1053 
1054         /**
1055          * Runs a second reduce phase across the output collection and the
1056          * map/reduce results.
1057          */
1058         REDUCE,
1059 
1060         /**
1061          * Replaces the contents of the output collection with the map/reduce
1062          * results.
1063          */
1064         REPLACE;
1065     }
1066 }