1 /*
2 * #%L
3 * Find.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 java.util.concurrent.TimeUnit;
24
25 import com.allanbank.mongodb.MongoClientConfiguration;
26 import com.allanbank.mongodb.MongoCollection;
27 import com.allanbank.mongodb.MongoCursorControl;
28 import com.allanbank.mongodb.MongoIterator;
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.Element;
34 import com.allanbank.mongodb.bson.builder.BuilderFactory;
35 import com.allanbank.mongodb.bson.builder.DocumentBuilder;
36 import com.allanbank.mongodb.bson.element.IntegerElement;
37
38 /**
39 * Find provides an immutable container for all of the options for a query.
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 2012-2013, Allanbank Consulting, Inc., All Rights Reserved
46 */
47 public class Find {
48 /** An (empty) query document to find all documents. */
49 public static final Document ALL = MongoCollection.ALL;
50
51 /**
52 * The first version of MongoDB to support the queries with the ability to
53 * limit the execution time on the server.
54 */
55 public static final Version MAX_TIMEOUT_VERSION = Version.parse("2.5.4");
56
57 /**
58 * Creates a new builder for a {@link Find}.
59 *
60 * @return The builder to construct a {@link Find}.
61 */
62 public static Builder builder() {
63 return new Builder();
64 }
65
66 /**
67 * If set to true requests for data will block, waiting for data. Useful
68 * with {@link Builder#tailable()} cursors.
69 */
70 private final boolean myAwaitData;
71
72 /** The number of documents to be returned in each batch of results. */
73 private final int myBatchSize;
74
75 /** The hint for which index to use. */
76 private final Document myHint;
77
78 /** The hint for which index to use by name. */
79 private final String myHintName;
80
81 /**
82 * If set to true the cursor returned from the query will not timeout or die
83 * automatically, e.g., immortal.
84 */
85 private final boolean myImmortalCursor;
86
87 /** The total number of documents to be returned. */
88 private final int myLimit;
89
90 /**
91 * If set then controls the maximum number of documents that will be scanned
92 * for results.
93 */
94 private final long myMaximumDocumentsToScan;
95
96 /**
97 * If set then controls the maximum value for the range within the used
98 * index.
99 */
100 private final Document myMaximumRange;
101
102 /** The maximum amount of time to allow the query to run. */
103 private final long myMaximumTimeMilliseconds;
104
105 /**
106 * If set then controls the minimum value for the range within the used
107 * index.
108 */
109 private final Document myMinimumRange;
110
111 /** The number of documents to skip before returning the first document. */
112 private final int myNumberToSkip;
113
114 /** If true then an error in the query should return any partial results. */
115 private final boolean myPartialOk;
116
117 /** The fields to be projected/returned from the matching documents. */
118 private final Document myProjection;
119
120 /** The query document. */
121 private final Document myQuery;
122
123 /** The preference for which servers to use to retrieve the results. */
124 private final ReadPreference myReadPreference;
125
126 /** If set to true then only the index keys will be returned. */
127 private final boolean myReturnIndexKeysOnly;
128
129 /**
130 * If set to true then a "$diskLoc" entry will be added to every returned
131 * document with the disk location information.
132 */
133 private final boolean myShowDiskLocation;
134
135 /**
136 * If set to true then use snapshot mode to ensure document are only
137 * returned once.
138 */
139 private final boolean mySnapshot;
140
141 /** The fields to order the document by. */
142 private final Document mySort;
143
144 /** If set to true the cursor returned from the query will be tailable. */
145 private final boolean myTailable;
146
147 /**
148 * Creates a new Find.
149 *
150 * @param builder
151 * The builder to copy the query fields from.
152 */
153 protected Find(final Builder builder) {
154 myBatchSize = builder.myBatchSize;
155 myHint = builder.myHint;
156 myHintName = builder.myHintName;
157 myLimit = builder.myLimit;
158 myNumberToSkip = builder.myNumberToSkip;
159 myPartialOk = builder.myPartialOk;
160 myQuery = builder.myQuery;
161 myReadPreference = builder.myReadPreference;
162 myProjection = builder.myProjection;
163 mySnapshot = builder.mySnapshot;
164 mySort = builder.mySort;
165 myTailable = builder.myTailable;
166 myAwaitData = builder.myAwaitData;
167 myImmortalCursor = builder.myImmortalCursor;
168 myMaximumRange = builder.myMaximumRange;
169 myMinimumRange = builder.myMinimumRange;
170 myMaximumDocumentsToScan = builder.myMaximumDocumentsToScan;
171 myMaximumTimeMilliseconds = builder.myMaximumTimeMilliseconds;
172 myReturnIndexKeysOnly = builder.myReturnIndexKeysOnly;
173 myShowDiskLocation = builder.myShowDiskLocation;
174 }
175
176 /**
177 * Returns the number of documents to be returned in each batch of results.
178 *
179 * @return The number of documents to be returned in each batch of results.
180 */
181 public int getBatchSize() {
182 return myBatchSize;
183 }
184
185 /**
186 * Returns the hint for which index to use.
187 *
188 * @return The hint for which index to use.
189 */
190 public Document getHint() {
191 return myHint;
192 }
193
194 /**
195 * Returns the hint for which index to use by name.
196 *
197 * @return The hint for which index to use by name.
198 */
199 public String getHintName() {
200 return myHintName;
201 }
202
203 /**
204 * Returns the total number of documents to be returned.
205 *
206 * @return The total number of documents to be returned.
207 */
208 public int getLimit() {
209 return myLimit;
210 }
211
212 /**
213 * Returns a value greater than zero to controls the maximum number of
214 * documents that will be scanned for results.
215 *
216 * @return A value greater than zero to controls the maximum number of
217 * documents that will be scanned for results.
218 *
219 * @see <a
220 * href="http://docs.mongodb.org/manual/reference/operator/maxScan/">$maxScan
221 * Documentation</a>
222 */
223 public long getMaximumDocumentsToScan() {
224 return myMaximumDocumentsToScan;
225 }
226
227 /**
228 * Returns a non-null value to controls the maximum value for the range
229 * within the used index.
230 *
231 * @return A non-null value to controls the maximum value for the range
232 * within the used index.
233 *
234 * @see <a
235 * href="http://docs.mongodb.org/manual/reference/operator/max/">$max
236 * Documentation</a>
237 */
238 public Document getMaximumRange() {
239 return myMaximumRange;
240 }
241
242 /**
243 * Returns the maximum amount of time to allow the query to run on the
244 * Server before it is aborted.
245 *
246 * @return The maximum amount of time to allow the query to run on the
247 * Server before it is aborted.
248 *
249 * @since MongoDB 2.6
250 */
251 public long getMaximumTimeMilliseconds() {
252 return myMaximumTimeMilliseconds;
253 }
254
255 /**
256 * Returns a non-null value to controls the minimum value for the range
257 * within the used index.
258 *
259 * @return A non-null value to controls the minimum value for the range
260 * within the used index.
261 *
262 * @see <a
263 * href="http://docs.mongodb.org/manual/reference/operator/min/">$min
264 * Documentation</a>
265 */
266 public Document getMinimumRange() {
267 return myMinimumRange;
268 }
269
270 /**
271 * Returns the number of documents to skip before returning the first
272 * document.
273 *
274 * @return The number of documents to skip before returning the first
275 * document.
276 */
277 public int getNumberToSkip() {
278 return myNumberToSkip;
279 }
280
281 /**
282 * Returns the fields to be projected or returned from the matching
283 * documents.
284 *
285 * @return The fields to be projected from the matching documents.
286 */
287 public Document getProjection() {
288 return myProjection;
289 }
290
291 /**
292 * Returns the query document.
293 *
294 * @return The query document.
295 */
296 public Document getQuery() {
297 return myQuery;
298 }
299
300 /**
301 * Returns the preference for the servers to retrieve the results from. May
302 * be <code>null</code> in which case the default read preference should be
303 * used.
304 *
305 * @return The preference for the servers to retrieve the results from.
306 */
307 public ReadPreference getReadPreference() {
308 return myReadPreference;
309 }
310
311 /**
312 * Returns the fields to be returned from the matching documents.
313 *
314 * @return The fields to be returned from the matching documents.
315 * @deprecated Replaced with the MongoDB standardized name:
316 * {@link #getProjection() projection}. This method will be
317 * removed on or after the 1.4 release.
318 */
319 @Deprecated
320 public Document getReturnFields() {
321 return myProjection;
322 }
323
324 /**
325 * Returns the fields to order document by.
326 *
327 * @return The fields to order document by.
328 */
329 public Document getSort() {
330 return mySort;
331 }
332
333 /**
334 * Returns true if the cursor returned from the query will block or wait for
335 * data. This is mainly useful with {@link Builder#tailable()} cursors.
336 *
337 * @return True if the cursor returned from the query will block or wait for
338 * data.
339 */
340 public boolean isAwaitData() {
341 return myAwaitData;
342 }
343
344 /**
345 * Returns true if the cursor returned from the query will not timeout or
346 * die automatically, e.g., immortal, false otherwise.
347 *
348 * @return True if the cursor returned from the query will not timeout or
349 * die automatically, e.g., immortal.
350 * @see Builder#setImmortalCursor(boolean)
351 * Find.Builder.setimmortalCursor(boolean) for important usage
352 * information.
353 */
354 public boolean isImmortalCursor() {
355 return myImmortalCursor;
356 }
357
358 /**
359 * Returns the partial okay value. If true then an error in the query should
360 * return any partial results.
361 *
362 * @return The partial okay value. If true then an error in the query should
363 * return any partial results.
364 */
365 public boolean isPartialOk() {
366 return myPartialOk;
367 }
368
369 /**
370 * Returns true if only the index keys will be returned.
371 *
372 * @return True if only the index keys will be returned.
373 *
374 * @see <a
375 * href="http://docs.mongodb.org/manual/reference/operator/returnKey/">$returnKey
376 * Documentation</a>
377 */
378 public boolean isReturnIndexKeysOnly() {
379 return myReturnIndexKeysOnly;
380 }
381
382 /**
383 * Returns true if a "$diskLoc" entry will be added to every returned
384 * document with the disk location information.
385 *
386 * @return True if a "$diskLoc" entry will be added to every returned
387 * document with the disk location information.
388 *
389 * @see <a
390 * href="http://docs.mongodb.org/manual/reference/operator/returnKey/">$showDiskLoc
391 * Documentation</a>
392 */
393 public boolean isShowDiskLocation() {
394 return myShowDiskLocation;
395 }
396
397 /**
398 * If returns true then use snapshot mode to ensure document are only
399 * returned once.
400 *
401 * @return True then use snapshot mode to ensure document are only returned
402 * once.
403 */
404 public boolean isSnapshot() {
405 return mySnapshot;
406 }
407
408 /**
409 * Returns true if the cursor returned from the query will be tailable,
410 * false otherwise.
411 *
412 * @return True if the cursor returned from the query will be tailable,
413 * false otherwise.
414 * @see Builder#setTailable(boolean) Find.Builder.setTailable(boolean) for
415 * important usage information.
416 */
417 public boolean isTailable() {
418 return myTailable;
419 }
420
421 /**
422 * This method is not intended for applications to use. Applications should
423 * pass the {@link Find} object to the appropriate method on the
424 * {@link MongoCollection} interface. This method is used internally by the
425 * driver and is public for cross package access only.
426 * <p>
427 * Converts the {@link Find} into a raw query request document to send to
428 * the MongoDB server.
429 * </p>
430 *
431 * @param explain
432 * If true then explain the query procedure instead of returning
433 * results.
434 * @return The query request document to send to the MongoDB server.
435 */
436 public Document toQueryRequest(final boolean explain) {
437 return toQueryRequest(explain, null);
438 }
439
440 /**
441 * This method is not intended for applications to use. Applications should
442 * pass the {@link Find} object to the appropriate method on the
443 * {@link MongoCollection} interface. This method is used internally by the
444 * driver and is public for cross package access only.
445 * <p>
446 * Converts the {@link Find} into a raw query request document to send to
447 * the MongoDB server including the provided read preferences.
448 * </p>
449 *
450 * @param explain
451 * If true then explain the query procedure instead of returning
452 * results.
453 * @param readPreference
454 * The read preference to include in the query request document.
455 * @return The query request document to send to the MongoDB server.
456 */
457 public Document toQueryRequest(final boolean explain,
458 final ReadPreference readPreference) {
459
460 if (explain || mySnapshot || myReturnIndexKeysOnly
461 || myShowDiskLocation || (mySort != null)
462 || (myMaximumDocumentsToScan > 0)
463 || (myMaximumTimeMilliseconds > 0) || (myHint != null)
464 || (myHintName != null) || (readPreference != null)
465 || (myMaximumRange != null) || (myMinimumRange != null)) {
466 final DocumentBuilder builder = BuilderFactory.start();
467
468 builder.add("$query", myQuery);
469
470 if (explain) {
471 builder.add("$explain", true);
472 }
473
474 if (myHint != null) {
475 builder.add("$hint", myHint);
476 }
477 else if (myHintName != null) {
478 builder.add("$hint", myHintName);
479 }
480
481 if (myMaximumRange != null) {
482 builder.add("$max", myMaximumRange);
483 }
484
485 if (myMaximumTimeMilliseconds > 0) {
486 builder.add("$maxTimeMS", myMaximumTimeMilliseconds);
487 }
488
489 if (myMaximumDocumentsToScan > 0) {
490 builder.add("$maxScan", myMaximumDocumentsToScan);
491 }
492
493 if (myMinimumRange != null) {
494 builder.add("$min", myMinimumRange);
495 }
496
497 if (mySort != null) {
498 builder.add("$orderby", mySort);
499 }
500
501 if (myReturnIndexKeysOnly) {
502 builder.add("$returnKey", true);
503 }
504
505 if (myShowDiskLocation) {
506 builder.add("$showDiskLoc", true);
507 }
508
509 if (mySnapshot) {
510 builder.add("$snapshot", true);
511 }
512
513 if (readPreference != null) {
514 builder.add(ReadPreference.FIELD_NAME, readPreference);
515 }
516
517 return builder.build();
518 }
519
520 return myQuery;
521 }
522
523 /**
524 * Helper for creating immutable {@link Find} queries.
525 *
526 * @api.yes This class is part of the driver's API. Public and protected
527 * members will be deprecated for at least 1 non-bugfix release
528 * (version numbers are <major>.<minor>.<bugfix>)
529 * before being removed or modified.
530 * @copyright 2012-2013, Allanbank Consulting, Inc., All Rights Reserved
531 */
532 public static class Builder {
533
534 /**
535 * If set to true requests for data will block, waiting for data. Useful
536 * with {@link #tailable()} cursors.
537 */
538 protected boolean myAwaitData;
539
540 /** The number of documents to be returned in each batch of results. */
541 protected int myBatchSize;
542
543 /** The hint for which index to use. */
544 protected Document myHint;
545
546 /** The hint for which index to use. */
547 protected String myHintName;
548
549 /**
550 * If set to true the cursor returned from the query will not timeout or
551 * die automatically, e.g., immortal.
552 */
553 protected boolean myImmortalCursor;
554
555 /** The total number of documents to be returned. */
556 protected int myLimit;
557
558 /**
559 * If set then controls the maximum number of documents that will be
560 * scanned for results.
561 */
562 protected long myMaximumDocumentsToScan;
563
564 /**
565 * If set then controls the maximum value for the range within the used
566 * index.
567 */
568 protected Document myMaximumRange;
569
570 /** The maximum amount of time to allow the query to run. */
571 protected long myMaximumTimeMilliseconds;
572
573 /**
574 * If set then controls the minimum value for the range within the used
575 * index.
576 */
577 protected Document myMinimumRange;
578
579 /** The number of documents to skip before returning the first document. */
580 protected int myNumberToSkip;
581
582 /**
583 * If true then an error in the query should return any partial results.
584 */
585 protected boolean myPartialOk;
586
587 /** The fields to be returned from the matching documents. */
588 protected Document myProjection;
589
590 /** The query document. */
591 protected Document myQuery;
592
593 /** The preference for which servers to use to retrieve the results. */
594 protected ReadPreference myReadPreference;
595
596 /** If set to true then only the index keys will be returned. */
597 protected boolean myReturnIndexKeysOnly;
598
599 /**
600 * If set to true then a "$diskLoc" entry will be added to every
601 * returned document with the disk location information.
602 */
603 protected boolean myShowDiskLocation;
604
605 /**
606 * If set to true then use snapshot mode to ensure document are only
607 * returned once.
608 */
609 protected boolean mySnapshot;
610
611 /** The fields to order the document on. */
612 protected Document mySort;
613
614 /** If set to true the cursor returned from the query will be tailable. */
615 protected boolean myTailable;
616
617 /**
618 * Creates a new Builder.
619 */
620 public Builder() {
621 reset();
622 }
623
624 /**
625 * Creates a new Builder.
626 *
627 * @param query
628 * The query document.
629 */
630 public Builder(final DocumentAssignable query) {
631 this();
632 myQuery = query.asDocument();
633 }
634
635 /**
636 * Sets the value of the number of documents to be returned in each
637 * batch.
638 * <p>
639 * This method delegates to {@link #setBatchSize(int)}.
640 * </p>
641 *
642 * @param batchSize
643 * The new value for the number of documents to be returned
644 * in each batch.
645 * @return This builder for chaining method calls.
646 */
647 public Builder batchSize(final int batchSize) {
648 return setBatchSize(batchSize);
649 }
650
651 /**
652 * Constructs a new {@link Find} object from the state of the builder.
653 *
654 * @return The new {@link Find} object.
655 */
656 public Find build() {
657 return new Find(this);
658 }
659
660 /**
661 * Sets the value of hint as to which index should be used to execute
662 * the query.
663 * <p>
664 * This method delegates to {@link #setHint(DocumentAssignable)}.
665 * </p>
666 *
667 * @param indexFields
668 * The new value for the fields of the index to use to
669 * execute the query.
670 * @return This builder for chaining method calls.
671 */
672 public Builder hint(final DocumentAssignable indexFields) {
673 return setHint(indexFields);
674 }
675
676 /**
677 * Sets the value of hint as to which index should be used to execute
678 * the query.
679 * <p>
680 * This method delegates to {@link #setHint(Element...)}.
681 * </p>
682 * <p>
683 * This method is intended to be used with the {@link Index} class's
684 * static methods: <blockquote>
685 *
686 * <pre>
687 * <code>
688 * import static {@link Index#asc(String) com.allanbank.mongodb.builder.Index.asc};
689 * import static {@link Index#desc(String) com.allanbank.mongodb.builder.Index.desc};
690 *
691 * Find.Builder builder = new Find.Builder();
692 *
693 * builder.setHint( asc("f"), desc("g") );
694 * ...
695 * </code>
696 * </pre>
697 *
698 * </blockquote>
699 *
700 * @param indexFields
701 * The new value for the fields of the index to use to
702 * execute the query.
703 * @return This builder for chaining method calls.
704 */
705 public Builder hint(final Element... indexFields) {
706 return setHint(indexFields);
707 }
708
709 /**
710 * Sets the value of hint as to which index should be used to execute
711 * the query.
712 * <p>
713 * This method delegates to the {@link #setHint(String)} method.
714 * </p>
715 *
716 * @param indexName
717 * The new value for the name of the index to use to execute
718 * the query.
719 * @return This builder for chaining method calls.
720 */
721 public Builder hint(final String indexName) {
722 return setHint(indexName);
723 }
724
725 /**
726 * Sets the cursor returned from the query to never timeout or die
727 * automatically, e.g., immortal.
728 * <p>
729 * This method delegates to {@link #setImmortalCursor(boolean)
730 * setImmortalCursor(true)}. See its JavaDoc for <b>important usage</b>
731 * guidelines.
732 * </p>
733 *
734 * @return This builder for chaining method calls.
735 */
736 public Builder immortalCursor() {
737 return setImmortalCursor(true);
738 }
739
740 /**
741 * If set to true the cursor returned from the query will not timeout or
742 * die automatically, e.g., immortal.
743 * <p>
744 * This method delegates to {@link #setImmortalCursor(boolean)}. See its
745 * JavaDoc <b>important usage</b> guidelines.
746 * </p>
747 *
748 * @param immortal
749 * True if the cursor returned from the query should be
750 * immortal.
751 * @return This builder for chaining method calls.
752 */
753 public Builder immortalCursor(final boolean immortal) {
754 return setImmortalCursor(immortal);
755 }
756
757 /**
758 * Sets the value of the total number of documents to be returned.
759 * <p>
760 * This method delegates to {@link #setLimit(int)}.
761 * </p>
762 *
763 * @param limit
764 * The new value for the total number of documents to be
765 * returned.
766 * @return This builder for chaining method calls.
767 */
768 public Builder limit(final int limit) {
769 return setLimit(limit);
770 }
771
772 /**
773 * Sets the value of maximum range for the index used to the new value.
774 * <p>
775 * This method delegates to {@link #setMaximumRange(DocumentAssignable)}
776 * .
777 * </p>
778 *
779 * @param maximumRange
780 * The new value for the maximum range for the index used.
781 * @return This builder for chaining method calls.
782 */
783 public Builder max(final DocumentAssignable maximumRange) {
784 return setMaximumRange(maximumRange);
785 }
786
787 /**
788 * Sets the maximum number of milliseconds to allow the query to run
789 * before aborting the request on the server.
790 * <p>
791 * This method equivalent to {@link #setMaximumTimeMilliseconds(long)
792 * setMaximumTimeMilliseconds(timeLimitUnits.toMillis(timeLimit)}.
793 * </p>
794 *
795 * @param timeLimit
796 * The new maximum amount of time to allow the query to run.
797 * @param timeLimitUnits
798 * The units for the maximum amount of time to allow the
799 * query to run.
800 *
801 * @return This {@link Builder} for method call chaining.
802 *
803 * @since MongoDB 2.6
804 */
805 public Builder maximumTime(final long timeLimit,
806 final TimeUnit timeLimitUnits) {
807 return setMaximumTimeMilliseconds(timeLimitUnits
808 .toMillis(timeLimit));
809 }
810
811 /**
812 * Sets the value of maximum number of documents that will be scanned
813 * for results to the new value.
814 * <p>
815 * This method Delegates to {@link #setMaximumDocumentsToScan(long)}.
816 * </p>
817 *
818 * @param maximumDocumentsToScan
819 * The new value for the maximum number of documents that
820 * will be scanned for results.
821 * @return This builder for chaining method calls.
822 */
823 public Builder maxScan(final long maximumDocumentsToScan) {
824 return setMaximumDocumentsToScan(maximumDocumentsToScan);
825 }
826
827 /**
828 * Sets the value of minimum range for the index used to the new value.
829 * <p>
830 * This method delegates to {@link #setMinimumRange(DocumentAssignable)}
831 * .
832 * </p>
833 *
834 * @param minimumRange
835 * The new value for the minimum range for the index used.
836 * @return This builder for chaining method calls.
837 */
838 public Builder min(final DocumentAssignable minimumRange) {
839 return setMinimumRange(minimumRange);
840 }
841
842 /**
843 * Sets that if there is an error then the query should return any
844 * partial results.
845 * <p>
846 * This method delegates to {@link #setPartialOk(boolean)
847 * setPartialOk(true)}.
848 * </p>
849 *
850 * @return This builder for chaining method calls.
851 */
852 public Builder partialOk() {
853 return setPartialOk(true);
854 }
855
856 /**
857 * Sets the value of partial okay to the new value. If true then an
858 * error in the query should return any partial results.
859 * <p>
860 * This method delegates to {@link #setPartialOk(boolean)}.
861 * </p>
862 *
863 * @param partialOk
864 * The new value for the partial okay.
865 * @return This builder for chaining method calls.
866 */
867 public Builder partialOk(final boolean partialOk) {
868 return setPartialOk(partialOk);
869 }
870
871 /**
872 * Sets the value of the fields to be projected from the matching
873 * documents to the new value.
874 * <p>
875 * This method delegates to {@link #setProjection(DocumentAssignable)} .
876 * </p>
877 *
878 * @param projection
879 * The new value for the fields to be projected from the
880 * matching documents.
881 * @return This builder for chaining method calls.
882 */
883 public Builder projection(final DocumentAssignable projection) {
884 return setProjection(projection);
885 }
886
887 /**
888 * Sets the value of the fields to be returned from the matching
889 * documents to the new value.
890 * <p>
891 * This method adds each field to a document with a value of {@code 1}
892 * and then delegates to the {@link #setProjection(DocumentAssignable)}
893 * method.
894 * </p>
895 *
896 * @param fieldNames
897 * The names of the fields to be returned.
898 * @return This builder for chaining method calls.
899 */
900 public Builder projection(final String... fieldNames) {
901 final DocumentBuilder builder = BuilderFactory.start();
902 for (final String fieldName : fieldNames) {
903 builder.add(fieldName, 1);
904 }
905 return setProjection(builder);
906 }
907
908 /**
909 * Sets the value of the query document to the new value.
910 * <p>
911 * This method delegates to {@link #setQuery(DocumentAssignable)}.
912 * </p>
913 *
914 * @param query
915 * The new value for the query document.
916 * @return This builder for chaining method calls.
917 */
918 public Builder query(final DocumentAssignable query) {
919 return setQuery(query);
920 }
921
922 /**
923 * Sets the preference for the set of servers to retrieve the results
924 * from.
925 * <p>
926 * This method delegates to {@link #setReadPreference(ReadPreference)}.
927 * </p>
928 *
929 * @param readPreference
930 * The new value for the preference of which server to return
931 * the results from.
932 * @return This builder for chaining method calls.
933 */
934 public Builder readPreference(final ReadPreference readPreference) {
935 return setReadPreference(readPreference);
936 }
937
938 /**
939 * Resets the builder back to its initial state for reuse.
940 *
941 * @return This builder for chaining method calls.
942 */
943 public Builder reset() {
944 myBatchSize = 0;
945 myHint = null;
946 myHintName = null;
947 myLimit = 0;
948 myNumberToSkip = 0;
949 myPartialOk = false;
950 myQuery = ALL;
951 myReadPreference = null;
952 myProjection = null;
953 mySnapshot = false;
954 mySort = null;
955 myTailable = false;
956 myAwaitData = false;
957 myImmortalCursor = false;
958 myMaximumRange = null;
959 myMaximumTimeMilliseconds = 0;
960 myMinimumRange = null;
961 myMaximumDocumentsToScan = -1;
962 myReturnIndexKeysOnly = false;
963 myShowDiskLocation = false;
964
965 return this;
966 }
967
968 /**
969 * Sets the value of the fields to be returned from the matching
970 * documents to the new value.
971 * <p>
972 * This method delegates to {@link #projection(DocumentAssignable)} .
973 * </p>
974 *
975 * @param returnFields
976 * The new value for the fields to be returned from the
977 * matching documents.
978 * @return This builder for chaining method calls.
979 * @deprecated Replaced with the MongoDB standardized name:
980 * {@link #projection(DocumentAssignable) projection}. This
981 * method will be removed on or after the 1.4 release.
982 */
983 @Deprecated
984 public Builder returnFields(final DocumentAssignable returnFields) {
985 return projection(returnFields);
986 }
987
988 /**
989 * Sets the value of the fields to be returned from the matching
990 * documents to the new value.
991 * <p>
992 * This method delegates to the {@link #projection(String[])} method.
993 * </p>
994 *
995 * @param fieldNames
996 * The names of the fields to be returned.
997 * @return This builder for chaining method calls.
998 * @deprecated Replaced with the MongoDB standardized name:
999 * {@link #projection(String[]) projection}. This method
1000 * will be removed on or after the 1.4 release.
1001 */
1002 @Deprecated
1003 public Builder returnFields(final String... fieldNames) {
1004 return projection(fieldNames);
1005 }
1006
1007 /**
1008 * Sets that only index keys should be returned.
1009 * <p>
1010 * This method delegates to {@link #setReturnIndexKeysOnly(boolean)
1011 * setReturnIndexKeysOnly(true)}
1012 * </p>
1013 *
1014 * @return This builder for chaining method calls.
1015 */
1016 public Builder returnKey() {
1017 return setReturnIndexKeysOnly(true);
1018 }
1019
1020 /**
1021 * Sets the value for if only index keys should be returned to the new
1022 * value.
1023 * <p>
1024 * This method delegates to {@link #setReturnIndexKeysOnly(boolean)}
1025 * </p>
1026 *
1027 * @param returnIndexKeysOnly
1028 * The new value for if only index keys should be returned.
1029 * @return This builder for chaining method calls.
1030 *
1031 * @see <a
1032 * href="http://docs.mongodb.org/manual/reference/operator/returnKey/">$returnKey
1033 * Documentation</a>
1034 */
1035 public Builder returnKey(final boolean returnIndexKeysOnly) {
1036 return setReturnIndexKeysOnly(returnIndexKeysOnly);
1037 }
1038
1039 /**
1040 * If set to true requests for data will block, waiting for data. Useful
1041 * with {@link #tailable()} cursors.
1042 *
1043 * @param awaitData
1044 * True if requests for data will block, waiting for data.
1045 * Useful with {@link #tailable()} cursors.
1046 * @return This builder for chaining method calls.
1047 */
1048 public Builder setAwaitData(final boolean awaitData) {
1049 myAwaitData = awaitData;
1050 return this;
1051 }
1052
1053 /**
1054 * Sets the value of the number of documents to be returned in each
1055 * batch.
1056 *
1057 * @param batchSize
1058 * The new value for the number of documents to be returned
1059 * in each batch.
1060 * @return This builder for chaining method calls.
1061 */
1062 public Builder setBatchSize(final int batchSize) {
1063 myBatchSize = batchSize;
1064 return this;
1065 }
1066
1067 /**
1068 * Sets the value of hint as to which index should be used to execute
1069 * the query.
1070 *
1071 * @param indexFields
1072 * The new value for the fields of the index to use to
1073 * execute the query.
1074 * @return This builder for chaining method calls.
1075 *
1076 * @see <a
1077 * href="http://docs.mongodb.org/manual/reference/operator/hint/">$hint
1078 * Documentation</a>
1079 */
1080 public Builder setHint(final DocumentAssignable indexFields) {
1081 myHintName = null;
1082 myHint = indexFields.asDocument();
1083 return this;
1084 }
1085
1086 /**
1087 * Sets the value of hint as to which index should be used to execute
1088 * the query.
1089 * <p>
1090 * This method is intended to be used with the {@link Index} class's
1091 * static methods: <blockquote>
1092 *
1093 * <pre>
1094 * <code>
1095 * import static {@link Index#asc(String) com.allanbank.mongodb.builder.Index.asc};
1096 * import static {@link Index#desc(String) com.allanbank.mongodb.builder.Index.desc};
1097 *
1098 * Find.Builder builder = new Find.Builder();
1099 *
1100 * builder.setHint( asc("f"), desc("g") );
1101 * ...
1102 * </code>
1103 * </pre>
1104 *
1105 * </blockquote>
1106 *
1107 * @param indexFields
1108 * The new value for the fields of the index to use to
1109 * execute the query.
1110 * @return This builder for chaining method calls.
1111 *
1112 * @see <a
1113 * href="http://docs.mongodb.org/manual/reference/operator/hint/">$hint
1114 * Documentation</a>
1115 */
1116 public Builder setHint(final Element... indexFields) {
1117 final DocumentBuilder builder = BuilderFactory.start();
1118 for (final Element sortField : indexFields) {
1119 builder.add(sortField);
1120 }
1121 myHintName = null;
1122 myHint = builder.build();
1123 return this;
1124 }
1125
1126 /**
1127 * Sets the value of hint as to which index should be used to execute
1128 * the query.
1129 *
1130 * @param indexName
1131 * The new value for the name of the index to use to execute
1132 * the query.
1133 * @return This builder for chaining method calls.
1134 *
1135 * @see <a
1136 * href="http://docs.mongodb.org/manual/reference/operator/hint/">$hint
1137 * Documentation</a>
1138 */
1139 public Builder setHint(final String indexName) {
1140 myHintName = indexName;
1141 myHint = null;
1142 return this;
1143 }
1144
1145 /**
1146 * If set to true the cursor returned from the query will not timeout or
1147 * die automatically, e.g., immortal. The user must either exhaust the
1148 * results of the query or explicitly close the {@link MongoIterator} or
1149 * {@link MongoCursorControl} returned.
1150 * <p>
1151 * Under normal circumstances using an immortal cursor is not needed and
1152 * its repeated incorrect usage could cause a memory leak on the MongoDB
1153 * server and impact performance. Extreme caution should be used to
1154 * ensure the number of active cursors on the server does not grow
1155 * without bounds.
1156 * </p>
1157 *
1158 * @param immortal
1159 * True if the cursor returned from the query should be
1160 * immortal.
1161 * @return This builder for chaining method calls.
1162 */
1163 public Builder setImmortalCursor(final boolean immortal) {
1164 myImmortalCursor = immortal;
1165 return this;
1166 }
1167
1168 /**
1169 * Sets the value of the total number of documents to be returned.
1170 *
1171 * @param limit
1172 * The new value for the total number of documents to be
1173 * returned.
1174 * @return This builder for chaining method calls.
1175 */
1176 public Builder setLimit(final int limit) {
1177 myLimit = limit;
1178 return this;
1179 }
1180
1181 /**
1182 * Sets the value of maximum number of documents that will be scanned
1183 * for results to the new value.
1184 * <p>
1185 * If set to a value greater than zero then controls the maximum number
1186 * of documents that will be scanned for results.
1187 * </p>
1188 *
1189 * @param maximumDocumentsToScan
1190 * The new value for the maximum number of documents that
1191 * will be scanned for results.
1192 * @return This builder for chaining method calls.
1193 *
1194 * @see <a
1195 * href="http://docs.mongodb.org/manual/reference/operator/maxScan/">$maxScan
1196 * Documentation</a>
1197 */
1198 public Builder setMaximumDocumentsToScan(
1199 final long maximumDocumentsToScan) {
1200 myMaximumDocumentsToScan = maximumDocumentsToScan;
1201 return this;
1202 }
1203
1204 /**
1205 * Sets the value of maximum range for the index used to the new value.
1206 * <p>
1207 * If set then controls the maximum value for the range within the used
1208 * index.
1209 * </p>
1210 *
1211 * @param maximumRange
1212 * The new value for the maximum range for the index used.
1213 * @return This builder for chaining method calls.
1214 *
1215 * @see <a
1216 * href="http://docs.mongodb.org/manual/reference/operator/max/">$max
1217 * Documentation</a>
1218 */
1219 public Builder setMaximumRange(final DocumentAssignable maximumRange) {
1220 if (maximumRange != null) {
1221 myMaximumRange = maximumRange.asDocument();
1222 }
1223 else {
1224 myMaximumRange = null;
1225 }
1226 return this;
1227 }
1228
1229 /**
1230 * Sets the maximum number of milliseconds to allow the query to run
1231 * before aborting the request on the server.
1232 *
1233 * @param maximumTimeMilliseconds
1234 * The new maximum number of milliseconds to allow the query
1235 * to run.
1236 * @return This {@link Builder} for method call chaining.
1237 *
1238 * @since MongoDB 2.6
1239 */
1240 public Builder setMaximumTimeMilliseconds(
1241 final long maximumTimeMilliseconds) {
1242 myMaximumTimeMilliseconds = maximumTimeMilliseconds;
1243 return this;
1244 }
1245
1246 /**
1247 * Sets the value of minimum range for the index used to the new value.
1248 * <p>
1249 * If set then controls the minimum value for the range within the used
1250 * index.
1251 * </p>
1252 *
1253 * @param minimumRange
1254 * The new value for the minimum range for the index used.
1255 * @return This builder for chaining method calls.
1256 *
1257 * @see <a
1258 * href="http://docs.mongodb.org/manual/reference/operator/min/">$min
1259 * Documentation</a>
1260 */
1261 public Builder setMinimumRange(final DocumentAssignable minimumRange) {
1262 if (minimumRange != null) {
1263 myMinimumRange = minimumRange.asDocument();
1264 }
1265 else {
1266 myMinimumRange = null;
1267 }
1268 return this;
1269 }
1270
1271 /**
1272 * Sets the value of the number of documents to skip before returning
1273 * the first document to the new value.
1274 *
1275 * @param numberToSkip
1276 * The new value for the number of documents to skip before
1277 * returning the first document.
1278 * @return This builder for chaining method calls.
1279 */
1280 public Builder setNumberToSkip(final int numberToSkip) {
1281 myNumberToSkip = numberToSkip;
1282 return this;
1283 }
1284
1285 /**
1286 * Sets the value of partial okay to the new value. If true then an
1287 * error in the query should return any partial results.
1288 *
1289 * @param partialOk
1290 * The new value for the partial okay.
1291 * @return This builder for chaining method calls.
1292 */
1293 public Builder setPartialOk(final boolean partialOk) {
1294 myPartialOk = partialOk;
1295 return this;
1296 }
1297
1298 /**
1299 * Sets the value of the fields to be projected or returned from the
1300 * matching documents to the new value.
1301 *
1302 * @param projection
1303 * The new value for the fields to be projected from the
1304 * matching documents.
1305 * @return This builder for chaining method calls.
1306 */
1307 public Builder setProjection(final DocumentAssignable projection) {
1308 myProjection = projection.asDocument();
1309 return this;
1310 }
1311
1312 /**
1313 * Sets the value of the query document to the new value.
1314 *
1315 * @param query
1316 * The new value for the query document.
1317 * @return This builder for chaining method calls.
1318 */
1319 public Builder setQuery(final DocumentAssignable query) {
1320 myQuery = query.asDocument();
1321 return this;
1322 }
1323
1324 /**
1325 * Sets the preference for the set of servers to retrieve the results
1326 * from.
1327 *
1328 * @param readPreference
1329 * The new value for the preference of which server to return
1330 * the results from.
1331 * @return This builder for chaining method calls.
1332 */
1333 public Builder setReadPreference(final ReadPreference readPreference) {
1334 myReadPreference = readPreference;
1335 return this;
1336 }
1337
1338 /**
1339 * Sets the value of the fields to be returned from the matching
1340 * documents to the new value.
1341 * <p>
1342 * This method delegates to {@link #setProjection(DocumentAssignable)} .
1343 * </p>
1344 *
1345 * @param returnFields
1346 * The new value for the fields to be returned from the
1347 * matching documents.
1348 * @return This builder for chaining method calls.
1349 * @deprecated Replaced with the MongoDB standardized name:
1350 * {@link #setProjection projection}. This method will be
1351 * removed on or after the 1.4 release.
1352 */
1353 @Deprecated
1354 public Builder setReturnFields(final DocumentAssignable returnFields) {
1355 return setProjection(returnFields);
1356 }
1357
1358 /**
1359 * Sets the value for if only index keys should be returned to the new
1360 * value.
1361 * <p>
1362 * If set to true then only the index keys will be returned.
1363 * </p>
1364 *
1365 * @param returnIndexKeysOnly
1366 * The new value for if only index keys should be returned.
1367 * @return This builder for chaining method calls.
1368 *
1369 * @see <a
1370 * href="http://docs.mongodb.org/manual/reference/operator/returnKey/">$returnKey
1371 * Documentation</a>
1372 */
1373 public Builder setReturnIndexKeysOnly(final boolean returnIndexKeysOnly) {
1374 myReturnIndexKeysOnly = returnIndexKeysOnly;
1375 return this;
1376 }
1377
1378 /**
1379 * Sets the value if the disk location for each document should be
1380 * returned to the new value.
1381 * <p>
1382 * If set to true then a "$diskLoc" entry will be added to every
1383 * returned document with the disk location information.
1384 * </p>
1385 *
1386 * @param showDiskLocation
1387 * The new value for the if the disk location for each
1388 * document should be returned.
1389 * @return This builder for chaining method calls.
1390 *
1391 * @see <a
1392 * href="http://docs.mongodb.org/manual/reference/operator/returnKey/">$showDiskLoc
1393 * Documentation</a>
1394 */
1395 public Builder setShowDiskLocation(final boolean showDiskLocation) {
1396 myShowDiskLocation = showDiskLocation;
1397 return this;
1398 }
1399
1400 /**
1401 * Sets the value of snapshot to the new value. If set to true then use
1402 * snapshot mode to ensure document are only returned once.
1403 *
1404 * @param snapshot
1405 * The new value for the partial okay.
1406 * @return This builder for chaining method calls.
1407 *
1408 * @see <a
1409 * href="http://docs.mongodb.org/manual/reference/operator/snapshot/">$snapshot
1410 * Documentation</a>
1411 */
1412 public Builder setSnapshot(final boolean snapshot) {
1413 mySnapshot = snapshot;
1414 return this;
1415 }
1416
1417 /**
1418 * Sets the value of the fields to to sort matching documents by.
1419 *
1420 * @param sortFields
1421 * The new value for the fields to sort matching documents
1422 * by.
1423 * @return This builder for chaining method calls.
1424 *
1425 * @see <a
1426 * href="http://docs.mongodb.org/manual/reference/operator/orderby/">$orderby
1427 * Documentation</a>
1428 */
1429 public Builder setSort(final DocumentAssignable sortFields) {
1430 mySort = sortFields.asDocument();
1431 return this;
1432 }
1433
1434 /**
1435 * Sets the value of the fields to to sort matching documents by.
1436 * <p>
1437 * This method is intended to be used with the {@link Sort} class's
1438 * static methods: <blockquote>
1439 *
1440 * <pre>
1441 * <code>
1442 * import static {@link Sort#asc(String) com.allanbank.mongodb.builder.Sort.asc};
1443 * import static {@link Sort#desc(String) com.allanbank.mongodb.builder.Sort.desc};
1444 *
1445 * Find.Builder builder = new Find.Builder();
1446 *
1447 * builder.setSort( asc("f"), desc("g") );
1448 * ...
1449 * </code>
1450 * </pre>
1451 *
1452 * </blockquote>
1453 *
1454 * @param sortFields
1455 * The new value for the fields to sort matching documents
1456 * by.
1457 * @return This builder for chaining method calls.
1458 *
1459 * @see <a
1460 * href="http://docs.mongodb.org/manual/reference/operator/orderby/">$orderby
1461 * Documentation</a>
1462 */
1463 public Builder setSort(final IntegerElement... sortFields) {
1464 final DocumentBuilder builder = BuilderFactory.start();
1465 for (final IntegerElement sortField : sortFields) {
1466 builder.add(sortField);
1467 }
1468 mySort = builder.build();
1469 return this;
1470 }
1471
1472 /**
1473 * If set to true the cursor returned from the query will be tailable.
1474 * <p>
1475 * Testing has shown that a tailable cursor on an empty collection will
1476 * not setup a cursor on the MongoDB server and will immediately return
1477 * false from {@link MongoIterator#hasNext()}.
1478 * </p>
1479 * <p>
1480 * When using a tailable cursor that has exhausted the available data
1481 * will cause the {@link MongoIterator#hasNext()} calls to block until
1482 * more data is available. The connection that is used to request more
1483 * documents will also be blocked for short intervals (measured to be
1484 * ~2.25 seconds with 2.0.7). Any requests submitted behind the cursors
1485 * request will also be blocked.
1486 * </p>
1487 * <p>
1488 * It is highly recommended that the number of connections within the
1489 * {@link MongoClientConfiguration} be at least 1 more than the maximum
1490 * number of active tailable cursors.
1491 * </p>
1492 *
1493 * @param tailable
1494 * The new value for if the cursor returned from the query
1495 * will be tailable.
1496 * @return This builder for chaining method calls.
1497 */
1498 public Builder setTailable(final boolean tailable) {
1499 myTailable = tailable;
1500
1501 return this;
1502 }
1503
1504 /**
1505 * Sets that the disk location for each document should be returned.
1506 * <p>
1507 * This method delegates to {@link #setShowDiskLocation(boolean)
1508 * setShowDiskLocation(true)}.
1509 * </p>
1510 *
1511 * @return This builder for chaining method calls.
1512 */
1513 public Builder showDiskLoc() {
1514 return setShowDiskLocation(true);
1515 }
1516
1517 /**
1518 * Sets the value if the disk location for each document should be
1519 * returned to the new value.
1520 * <p>
1521 * This method delegates to {@link #setShowDiskLocation(boolean)}.
1522 * </p>
1523 *
1524 * @param showDiskLocation
1525 * The new value for the if the disk location for each
1526 * document should be returned.
1527 * @return This builder for chaining method calls.
1528 */
1529 public Builder showDiskLoc(final boolean showDiskLocation) {
1530 return setShowDiskLocation(showDiskLocation);
1531 }
1532
1533 /**
1534 * Sets the value of the number of documents to skip before returning
1535 * the first document to the new value.
1536 * <p>
1537 * This method delegates to {@link #setNumberToSkip(int)}.
1538 * </p>
1539 *
1540 * @param numberToSkip
1541 * The new value for the number of documents to skip before
1542 * returning the first document.
1543 * @return This builder for chaining method calls.
1544 */
1545 public Builder skip(final int numberToSkip) {
1546 return setNumberToSkip(numberToSkip);
1547 }
1548
1549 /**
1550 * Sets that the query should ensure that documents are only returned
1551 * once.
1552 * <p>
1553 * This method delegates to {@link #setSnapshot(boolean)
1554 * setSnapshot(true)}.
1555 * </p>
1556 *
1557 * @return This builder for chaining method calls.
1558 */
1559 public Builder snapshot() {
1560 return setSnapshot(true);
1561 }
1562
1563 /**
1564 * Sets the value of snapshot to the new value. If set to true then use
1565 * snapshot mode to ensure document are only returned once.
1566 * <p>
1567 * This method delegates to {@link #setSnapshot(boolean)}.
1568 * </p>
1569 *
1570 *
1571 * @param snapshot
1572 * The new value for the partial okay.
1573 * @return This builder for chaining method calls.
1574 */
1575 public Builder snapshot(final boolean snapshot) {
1576 return setSnapshot(snapshot);
1577 }
1578
1579 /**
1580 * Sets the value of the fields to to sort matching documents by.
1581 * <p>
1582 * This method delegates to {@link #setSort(DocumentAssignable)}.
1583 * </p>
1584 *
1585 * @param sortFields
1586 * The new value for the fields to sort matching documents
1587 * by.
1588 * @return This builder for chaining method calls.
1589 */
1590 public Builder sort(final DocumentAssignable sortFields) {
1591 return setSort(sortFields);
1592 }
1593
1594 /**
1595 * Sets the value of the fields to to sort matching documents by.
1596 * <p>
1597 * This method delegates to {@link #setSort(IntegerElement...)}.
1598 * </p>
1599 * <p>
1600 * This method is intended to be used with the {@link Sort} class's
1601 * static methods: <blockquote>
1602 *
1603 * <pre>
1604 * <code>
1605 * import static {@link Sort#asc(String) com.allanbank.mongodb.builder.Sort.asc};
1606 * import static {@link Sort#desc(String) com.allanbank.mongodb.builder.Sort.desc};
1607 *
1608 * Find.Builder builder = new Find.Builder();
1609 *
1610 * builder.sort( asc("f"), desc("g") );
1611 * ...
1612 * </code>
1613 * </pre>
1614 *
1615 * </blockquote>
1616 *
1617 * @param sortFields
1618 * The new value for the fields to sort matching documents
1619 * by.
1620 * @return This builder for chaining method calls.
1621 */
1622 public Builder sort(final IntegerElement... sortFields) {
1623 return setSort(sortFields);
1624 }
1625
1626 /**
1627 * Sets the the cursor returned from the query to be
1628 * {@link #setTailable(boolean) setTailable(true)} and
1629 * {@link #setAwaitData(boolean) setAwaitData(true)}.
1630 *
1631 * @return This builder for chaining method calls.
1632 * @see #setTailable(boolean) setTailable(boolean) for important usage
1633 * information.
1634 */
1635 public Builder tailable() {
1636 return setTailable(true).setAwaitData(true);
1637 }
1638 }
1639 }