View Javadoc
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 &lt;major&gt;.&lt;minor&gt;.&lt;bugfix&gt;)
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 }