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 <major>.<minor>.<bugfix>)
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 * <major>.<minor>.<bugfix>) 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 }