View Javadoc
1   /*
2    * #%L
3    * ConditionBuilder.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.awt.geom.Point2D;
24  import java.util.ArrayList;
25  import java.util.Date;
26  import java.util.LinkedHashMap;
27  import java.util.List;
28  import java.util.Map;
29  import java.util.UUID;
30  import java.util.regex.Pattern;
31  
32  import com.allanbank.mongodb.bson.Document;
33  import com.allanbank.mongodb.bson.DocumentAssignable;
34  import com.allanbank.mongodb.bson.Element;
35  import com.allanbank.mongodb.bson.ElementType;
36  import com.allanbank.mongodb.bson.builder.ArrayBuilder;
37  import com.allanbank.mongodb.bson.builder.BuilderFactory;
38  import com.allanbank.mongodb.bson.builder.DocumentBuilder;
39  import com.allanbank.mongodb.bson.element.ArrayElement;
40  import com.allanbank.mongodb.bson.element.BinaryElement;
41  import com.allanbank.mongodb.bson.element.BooleanElement;
42  import com.allanbank.mongodb.bson.element.DocumentElement;
43  import com.allanbank.mongodb.bson.element.DoubleElement;
44  import com.allanbank.mongodb.bson.element.IntegerElement;
45  import com.allanbank.mongodb.bson.element.JavaScriptElement;
46  import com.allanbank.mongodb.bson.element.JavaScriptWithScopeElement;
47  import com.allanbank.mongodb.bson.element.LongElement;
48  import com.allanbank.mongodb.bson.element.MaxKeyElement;
49  import com.allanbank.mongodb.bson.element.MinKeyElement;
50  import com.allanbank.mongodb.bson.element.MongoTimestampElement;
51  import com.allanbank.mongodb.bson.element.NullElement;
52  import com.allanbank.mongodb.bson.element.ObjectId;
53  import com.allanbank.mongodb.bson.element.ObjectIdElement;
54  import com.allanbank.mongodb.bson.element.RegularExpressionElement;
55  import com.allanbank.mongodb.bson.element.StringElement;
56  import com.allanbank.mongodb.bson.element.SymbolElement;
57  import com.allanbank.mongodb.bson.element.TimestampElement;
58  import com.allanbank.mongodb.bson.element.UuidElement;
59  import com.allanbank.mongodb.builder.expression.Constant;
60  import com.allanbank.mongodb.builder.expression.Expressions;
61  import com.allanbank.mongodb.error.QueryFailedException;
62  
63  /**
64   * ConditionBuilder provides tracking for the condition of a single field within
65   * a query.
66   * <p>
67   * Use the {@link QueryBuilder#where(String)} method to create a
68   * {@link ConditionBuilder}.
69   * </p>
70   * 
71   * @see QueryBuilder#whereField(String)
72   * @api.yes This class is part of the driver's API. Public and protected members
73   *          will be deprecated for at least 1 non-bugfix release (version
74   *          numbers are &lt;major&gt;.&lt;minor&gt;.&lt;bugfix&gt;) before being
75   *          removed or modified.
76   * @copyright 2012-2013, Allanbank Consulting, Inc., All Rights Reserved
77   */
78  public class ConditionBuilder implements DocumentAssignable {
79  
80      /** The equals element. */
81      private Element myEqualsComparison;
82  
83      /** The name of the field to compare. */
84      private final String myFieldName;
85  
86      /** The non-equal comparisons. */
87      private final Map<Operator, Element> myOtherComparisons;
88  
89      /** The parent builder for the condition. */
90      private final QueryBuilder myParent;
91  
92      /**
93       * Creates a new ConditionBuilder.
94       * <p>
95       * This constructor is protected since generally users will use the
96       * {@link QueryBuilder} class to create a condition builder.
97       * </p>
98       * 
99       * @param fieldName
100      *            The name for the field to compare.
101      * @param parent
102      *            The parent builder for this condition.
103      */
104     protected ConditionBuilder(final String fieldName, final QueryBuilder parent) {
105         myFieldName = fieldName;
106         myParent = parent;
107 
108         myOtherComparisons = new LinkedHashMap<Operator, Element>();
109     }
110 
111     /**
112      * Checks if the value is greater than the specified <tt>dateTime</tt>.
113      * <p>
114      * This is equivalent to {@link #greaterThanTimestamp(long)
115      * greaterThanTimestamp(dateTime.getTime())}.
116      * </p>
117      * <p>
118      * Only a single {@link #greaterThan(int) greaterThan(...)} comparison can
119      * be used. Calling multiple {@link #greaterThan(byte[]) greaterThan(...)}
120      * methods overwrites previous values. In addition any
121      * {@link #equals(boolean) equals(...)} condition is removed since no
122      * equality operator is supported by MongoDB.
123      * </p>
124      * 
125      * @param dateTime
126      *            The value to compare the field against.
127      * @return The condition builder for chaining method calls.
128      * @see #greaterThanTimestamp(long)
129      */
130     public ConditionBuilder after(final Date dateTime) {
131         return greaterThanTimestamp(dateTime.getTime());
132     }
133 
134     /**
135      * Specify the values that must <em>all</em> be in the fields array.
136      * <p>
137      * Only a single {@link #all(ArrayBuilder)} comparison can be used. Calling
138      * multiple <tt>all(...)</tt> methods overwrites previous values. In
139      * addition any {@link #equals(boolean) equals(...)} condition is removed
140      * since no equality operator is supported by MongoDB.
141      * </p>
142      * 
143      * @param elements
144      *            A builder for the values for the comparison. Any changes to
145      *            the {@link ArrayBuilder} after this method is called are not
146      *            reflected in the comparison.
147      * @return The condition builder for chaining method calls.
148      */
149     public ConditionBuilder all(final ArrayBuilder elements) {
150         return all(elements.build());
151     }
152 
153     /**
154      * Specify the values that must <em>all</em> be in the fields array.
155      * <p>
156      * This method can only be used with values of the same BSON type. If mixed
157      * types need to be used there are several options:
158      * <ul>
159      * <li>Use the {@link Expressions#constant Expressions#constant(...)}
160      * helpers with the {@link #all(Constant...)} method.</li>
161      * <li>Use the {@link ArrayBuilder} with the {@link #all(ArrayBuilder)}
162      * method.</li>
163      * <li>Manually construct the {@link Element elements} and use the
164      * {@link #all(Element...)} method.</li>
165      * </ul>
166      * </p>
167      * <p>
168      * Only a single {@link #all(ArrayBuilder)} comparison can be used. Calling
169      * multiple <tt>all(...)</tt> methods overwrites previous values. In
170      * addition any {@link #equals(boolean) equals(...)} condition is removed
171      * since no equality operator is supported by MongoDB.
172      * </p>
173      * 
174      * @param values
175      *            The values for the comparison.
176      * @return The condition builder for chaining method calls.
177      */
178     public ConditionBuilder all(final boolean... values) {
179         final ArrayBuilder arrayBuilder = BuilderFactory.startArray();
180         for (final boolean value : values) {
181             arrayBuilder.add(value);
182         }
183         return all(arrayBuilder);
184     }
185 
186     /**
187      * Specify the values that must <em>all</em> be in the fields array.
188      * <p>
189      * This method can only be used with values of the same BSON type. If mixed
190      * types need to be used there are several options:
191      * <ul>
192      * <li>Use the {@link Expressions#constant Expressions#constant(...)}
193      * helpers with the {@link #all(Constant...)} method.</li>
194      * <li>Use the {@link ArrayBuilder} with the {@link #all(ArrayBuilder)}
195      * method.</li>
196      * <li>Manually construct the {@link Element elements} and use the
197      * {@link #all(Element...)} method.</li>
198      * </ul>
199      * </p>
200      * <p>
201      * Only a single {@link #all(ArrayBuilder)} comparison can be used. Calling
202      * multiple <tt>all(...)</tt> methods overwrites previous values. In
203      * addition any {@link #equals(boolean) equals(...)} condition is removed
204      * since no equality operator is supported by MongoDB.
205      * </p>
206      * 
207      * @param values
208      *            The values for the comparison.
209      * @return The condition builder for chaining method calls.
210      */
211     public ConditionBuilder all(final byte[]... values) {
212         final ArrayBuilder arrayBuilder = BuilderFactory.startArray();
213         for (final byte[] value : values) {
214             arrayBuilder.add(value);
215         }
216         return all(arrayBuilder);
217     }
218 
219     /**
220      * Specify the values that must <em>all</em> be in the fields array.
221      * <p>
222      * This method is designed to be used with the {@link Expressions#constant
223      * Expressions.constant(...)} helper methods.<blockquote>
224      * 
225      * <pre>
226      * <code>
227      * import static {@link Expressions#constant com.allanbank.mongodb.builder.expression.Expressions.constant};
228      * 
229      * DocumentAssignable query = QueryBuilder.where("f").all(constant(1), constant(2), constant(3));
230      * </code>
231      * </pre>
232      * 
233      * </blockquote>
234      * </p>
235      * <p>
236      * Only a single {@link #all(Element[])} comparison can be used. Calling
237      * multiple <tt>all(...)</tt> methods overwrites previous values. In
238      * addition any {@link #equals(boolean) equals(...)} condition is removed
239      * since no equality operator is supported by MongoDB.
240      * </p>
241      * 
242      * @param values
243      *            The values for the comparison.
244      * @return The condition builder for chaining method calls.
245      */
246     public ConditionBuilder all(final Constant... values) {
247         myEqualsComparison = null;
248 
249         final List<Element> elements = new ArrayList<Element>(values.length);
250         for (int i = 0; i < values.length; ++i) {
251             elements.add(values[i].toElement(ArrayElement.nameFor(i)));
252         }
253         myOtherComparisons.put(MiscellaneousOperator.ALL, new ArrayElement(
254                 MiscellaneousOperator.ALL.getToken(), elements));
255 
256         return this;
257     }
258 
259     /**
260      * Specify the values that must <em>all</em> be in the fields array.
261      * <p>
262      * This method can only be used with values of the same BSON type. If mixed
263      * types need to be used there are several options:
264      * <ul>
265      * <li>Use the {@link Expressions#constant Expressions#constant(...)}
266      * helpers with the {@link #all(Constant...)} method.</li>
267      * <li>Use the {@link ArrayBuilder} with the {@link #all(ArrayBuilder)}
268      * method.</li>
269      * <li>Manually construct the {@link Element elements} and use the
270      * {@link #all(Element...)} method.</li>
271      * </ul>
272      * </p>
273      * <p>
274      * Only a single {@link #all(ArrayBuilder)} comparison can be used. Calling
275      * multiple <tt>all(...)</tt> methods overwrites previous values. In
276      * addition any {@link #equals(boolean) equals(...)} condition is removed
277      * since no equality operator is supported by MongoDB.
278      * </p>
279      * 
280      * @param values
281      *            The values for the comparison.
282      * @return The condition builder for chaining method calls.
283      */
284     public ConditionBuilder all(final Date... values) {
285         final ArrayBuilder arrayBuilder = BuilderFactory.startArray();
286         for (final Date value : values) {
287             arrayBuilder.add(value);
288         }
289         return all(arrayBuilder);
290     }
291 
292     /**
293      * Specify the values that must <em>all</em> be in the fields array.
294      * <p>
295      * This method can only be used with values of the same BSON type. If mixed
296      * types need to be used there are several options:
297      * <ul>
298      * <li>Use the {@link Expressions#constant Expressions#constant(...)}
299      * helpers with the {@link #all(Constant...)} method.</li>
300      * <li>Use the {@link ArrayBuilder} with the {@link #all(ArrayBuilder)}
301      * method.</li>
302      * <li>Manually construct the {@link Element elements} and use the
303      * {@link #all(Element...)} method.</li>
304      * </ul>
305      * </p>
306      * <p>
307      * Only a single {@link #all(ArrayBuilder)} comparison can be used. Calling
308      * multiple <tt>all(...)</tt> methods overwrites previous values. In
309      * addition any {@link #equals(boolean) equals(...)} condition is removed
310      * since no equality operator is supported by MongoDB.
311      * </p>
312      * 
313      * @param values
314      *            The values for the comparison.
315      * @return The condition builder for chaining method calls.
316      */
317     public ConditionBuilder all(final DocumentAssignable... values) {
318         final ArrayBuilder arrayBuilder = BuilderFactory.startArray();
319         for (final DocumentAssignable value : values) {
320             arrayBuilder.add(value);
321         }
322         return all(arrayBuilder);
323     }
324 
325     /**
326      * Specify the values that must <em>all</em> be in the fields array.
327      * <p>
328      * This method can only be used with values of the same BSON type. If mixed
329      * types need to be used there are several options:
330      * <ul>
331      * <li>Use the {@link Expressions#constant Expressions#constant(...)}
332      * helpers with the {@link #all(Constant...)} method.</li>
333      * <li>Use the {@link ArrayBuilder} with the {@link #all(ArrayBuilder)}
334      * method.</li>
335      * <li>Manually construct the {@link Element elements} and use the
336      * {@link #all(Element...)} method.</li>
337      * </ul>
338      * </p>
339      * <p>
340      * Only a single {@link #all(ArrayBuilder)} comparison can be used. Calling
341      * multiple <tt>all(...)</tt> methods overwrites previous values. In
342      * addition any {@link #equals(boolean) equals(...)} condition is removed
343      * since no equality operator is supported by MongoDB.
344      * </p>
345      * 
346      * @param values
347      *            The values for the comparison.
348      * @return The condition builder for chaining method calls.
349      */
350     public ConditionBuilder all(final Double... values) {
351         final ArrayBuilder arrayBuilder = BuilderFactory.startArray();
352         for (final Double value : values) {
353             arrayBuilder.add(value.doubleValue());
354         }
355         return all(arrayBuilder);
356     }
357 
358     /**
359      * Specify the values that must <em>all</em> be in the fields array.
360      * <p>
361      * Only a single {@link #all(Element[])} comparison can be used. Calling
362      * multiple <tt>all(...)</tt> methods overwrites previous values. In
363      * addition any {@link #equals(boolean) equals(...)} condition is removed
364      * since no equality operator is supported by MongoDB.
365      * </p>
366      * 
367      * @param elements
368      *            The element values for the comparison.
369      * @return The condition builder for chaining method calls.
370      */
371     public ConditionBuilder all(final Element... elements) {
372         myEqualsComparison = null;
373         myOtherComparisons.put(MiscellaneousOperator.ALL, new ArrayElement(
374                 MiscellaneousOperator.ALL.getToken(), elements));
375 
376         return this;
377     }
378 
379     /**
380      * Specify the values that must <em>all</em> be in the fields array.
381      * <p>
382      * This method can only be used with values of the same BSON type. If mixed
383      * types need to be used there are several options:
384      * <ul>
385      * <li>Use the {@link Expressions#constant Expressions#constant(...)}
386      * helpers with the {@link #all(Constant...)} method.</li>
387      * <li>Use the {@link ArrayBuilder} with the {@link #all(ArrayBuilder)}
388      * method.</li>
389      * <li>Manually construct the {@link Element elements} and use the
390      * {@link #all(Element...)} method.</li>
391      * </ul>
392      * </p>
393      * <p>
394      * Only a single {@link #all(ArrayBuilder)} comparison can be used. Calling
395      * multiple <tt>all(...)</tt> methods overwrites previous values. In
396      * addition any {@link #equals(boolean) equals(...)} condition is removed
397      * since no equality operator is supported by MongoDB.
398      * </p>
399      * 
400      * @param values
401      *            The values for the comparison.
402      * @return The condition builder for chaining method calls.
403      */
404     public ConditionBuilder all(final Integer... values) {
405         final ArrayBuilder arrayBuilder = BuilderFactory.startArray();
406         for (final Integer value : values) {
407             arrayBuilder.add(value.intValue());
408         }
409         return all(arrayBuilder);
410     }
411 
412     /**
413      * Specify the values that must <em>all</em> be in the fields array.
414      * <p>
415      * This method can only be used with values of the same BSON type. If mixed
416      * types need to be used there are several options:
417      * <ul>
418      * <li>Use the {@link Expressions#constant Expressions#constant(...)}
419      * helpers with the {@link #all(Constant...)} method.</li>
420      * <li>Use the {@link ArrayBuilder} with the {@link #all(ArrayBuilder)}
421      * method.</li>
422      * <li>Manually construct the {@link Element elements} and use the
423      * {@link #all(Element...)} method.</li>
424      * </ul>
425      * </p>
426      * <p>
427      * Only a single {@link #all(ArrayBuilder)} comparison can be used. Calling
428      * multiple <tt>all(...)</tt> methods overwrites previous values. In
429      * addition any {@link #equals(boolean) equals(...)} condition is removed
430      * since no equality operator is supported by MongoDB.
431      * </p>
432      * 
433      * @param values
434      *            The values for the comparison.
435      * @return The condition builder for chaining method calls.
436      */
437     public ConditionBuilder all(final Long... values) {
438         final ArrayBuilder arrayBuilder = BuilderFactory.startArray();
439         for (final Long value : values) {
440             arrayBuilder.add(value.longValue());
441         }
442         return all(arrayBuilder);
443     }
444 
445     /**
446      * Specify the values that must <em>all</em> be in the fields array.
447      * <p>
448      * This method can only be used with values of the same BSON type. If mixed
449      * types need to be used there are several options:
450      * <ul>
451      * <li>Use the {@link Expressions#constant Expressions#constant(...)}
452      * helpers with the {@link #all(Constant...)} method.</li>
453      * <li>Use the {@link ArrayBuilder} with the {@link #all(ArrayBuilder)}
454      * method.</li>
455      * <li>Manually construct the {@link Element elements} and use the
456      * {@link #all(Element...)} method.</li>
457      * </ul>
458      * </p>
459      * <p>
460      * Only a single {@link #all(ArrayBuilder)} comparison can be used. Calling
461      * multiple <tt>all(...)</tt> methods overwrites previous values. In
462      * addition any {@link #equals(boolean) equals(...)} condition is removed
463      * since no equality operator is supported by MongoDB.
464      * </p>
465      * 
466      * @param values
467      *            The values for the comparison.
468      * @return The condition builder for chaining method calls.
469      */
470     public ConditionBuilder all(final ObjectId... values) {
471         final ArrayBuilder arrayBuilder = BuilderFactory.startArray();
472         for (final ObjectId value : values) {
473             arrayBuilder.add(value);
474         }
475         return all(arrayBuilder);
476     }
477 
478     /**
479      * Specify the values that must <em>all</em> be in the fields array.
480      * <p>
481      * This method can only be used with values of the same BSON type. If mixed
482      * types need to be used there are several options:
483      * <ul>
484      * <li>Use the {@link Expressions#constant Expressions#constant(...)}
485      * helpers with the {@link #all(Constant...)} method.</li>
486      * <li>Use the {@link ArrayBuilder} with the {@link #all(ArrayBuilder)}
487      * method.</li>
488      * <li>Manually construct the {@link Element elements} and use the
489      * {@link #all(Element...)} method.</li>
490      * </ul>
491      * </p>
492      * <p>
493      * Only a single {@link #all(ArrayBuilder)} comparison can be used. Calling
494      * multiple <tt>all(...)</tt> methods overwrites previous values. In
495      * addition any {@link #equals(boolean) equals(...)} condition is removed
496      * since no equality operator is supported by MongoDB.
497      * </p>
498      * 
499      * @param values
500      *            The values for the comparison.
501      * @return The condition builder for chaining method calls.
502      */
503     public ConditionBuilder all(final Pattern... values) {
504         final ArrayBuilder arrayBuilder = BuilderFactory.startArray();
505         for (final Pattern value : values) {
506             arrayBuilder.add(value);
507         }
508         return all(arrayBuilder);
509     }
510 
511     /**
512      * Specify the values that must <em>all</em> be in the fields array.
513      * <p>
514      * This method can only be used with values of the same BSON type. If mixed
515      * types need to be used there are several options:
516      * <ul>
517      * <li>Use the {@link Expressions#constant Expressions#constant(...)}
518      * helpers with the {@link #all(Constant...)} method.</li>
519      * <li>Use the {@link ArrayBuilder} with the {@link #all(ArrayBuilder)}
520      * method.</li>
521      * <li>Manually construct the {@link Element elements} and use the
522      * {@link #all(Element...)} method.</li>
523      * </ul>
524      * </p>
525      * <p>
526      * Only a single {@link #all(ArrayBuilder)} comparison can be used. Calling
527      * multiple <tt>all(...)</tt> methods overwrites previous values. In
528      * addition any {@link #equals(boolean) equals(...)} condition is removed
529      * since no equality operator is supported by MongoDB.
530      * </p>
531      * 
532      * @param values
533      *            The values for the comparison.
534      * @return The condition builder for chaining method calls.
535      */
536     public ConditionBuilder all(final String... values) {
537         final ArrayBuilder arrayBuilder = BuilderFactory.startArray();
538         for (final String value : values) {
539             arrayBuilder.add(value);
540         }
541         return all(arrayBuilder);
542     }
543 
544     /**
545      * Specify the values that must <em>all</em> be in the fields array.
546      * <p>
547      * This method can only be used with values of the same BSON type. If mixed
548      * types need to be used there are several options:
549      * <ul>
550      * <li>Use the {@link Expressions#constant Expressions#constant(...)}
551      * helpers with the {@link #all(Constant...)} method.</li>
552      * <li>Use the {@link ArrayBuilder} with the {@link #all(ArrayBuilder)}
553      * method.</li>
554      * <li>Manually construct the {@link Element elements} and use the
555      * {@link #all(Element...)} method.</li>
556      * </ul>
557      * </p>
558      * <p>
559      * Only a single {@link #all(ArrayBuilder)} comparison can be used. Calling
560      * multiple <tt>all(...)</tt> methods overwrites previous values. In
561      * addition any {@link #equals(boolean) equals(...)} condition is removed
562      * since no equality operator is supported by MongoDB.
563      * </p>
564      * 
565      * @param values
566      *            The values for the comparison.
567      * @return The condition builder for chaining method calls.
568      */
569     public ConditionBuilder all(final UUID... values) {
570         final ArrayBuilder arrayBuilder = BuilderFactory.startArray();
571         for (final UUID value : values) {
572             arrayBuilder.add(value);
573         }
574         return all(arrayBuilder);
575     }
576 
577     /**
578      * Starts a logical conjunction with this condition builder. If the
579      * <tt>fieldName</tt> is equal to this builder's {@link #getFieldName()
580      * field name} then this builder will be returned. Otherwise a different
581      * builder will be returned sharing the same parent {@link QueryBuilder}.
582      * 
583      * @param fieldName
584      *            The name of the field to create a conjunction with.
585      * @return The {@link ConditionBuilder} to use to construct the conjunction.
586      */
587     public ConditionBuilder and(final String fieldName) {
588         return myParent.whereField(fieldName);
589     }
590 
591     /**
592      * {@inheritDoc}
593      * <p>
594      * Returns the result of {@link #build()}.
595      * </p>
596      * 
597      * @see #build()
598      */
599     @Override
600     public Document asDocument() {
601         return build();
602     }
603 
604     /**
605      * Checks if the value is less than the specified <tt>dateTime</tt>.
606      * <p>
607      * This is equivalent to {@link #lessThanTimestamp(long)
608      * lessThanTimestamp(dateTime.getTime())}.
609      * </p>
610      * <p>
611      * Only a single {@link #lessThan(int) lessThan(...)} comparison can be
612      * used. Calling multiple {@link #lessThan(byte[]) lessThan(...)} methods
613      * overwrites previous values. In addition any {@link #equals(boolean)
614      * equals(...)} condition is removed since no equality operator is supported
615      * by MongoDB.
616      * </p>
617      * 
618      * @param dateTime
619      *            The value to compare the field against.
620      * @return The condition builder for chaining method calls.
621      * @see #lessThanTimestamp(long)
622      */
623     public ConditionBuilder before(final Date dateTime) {
624         return lessThanTimestamp(dateTime.getTime());
625     }
626 
627     /**
628      * Returns the results of building the parent {@link QueryBuilder}.
629      * 
630      * @return The results of building the parent {@link QueryBuilder}.
631      * 
632      * @see QueryBuilder#build()
633      */
634     public Document build() {
635         return myParent.build();
636     }
637 
638     /**
639      * Adds a {@link MiscellaneousOperator#COMMENT $comment} to the query.
640      * Comments are useful for locating queries in the profiler log within
641      * MongoDB.
642      * <p>
643      * Note that the {@link MiscellaneousOperator#COMMENT $comment} operator
644      * does not apply to a specific field but applies to the document as a
645      * whole. For this reason only a single {@link #comment} condition can be
646      * used. Calling multiple <tt>comment(...)</tt> methods overwrites previous
647      * values.
648      * </p>
649      * 
650      * @param comment
651      *            The comment to add to the query.
652      * @return This builder for call chaining.
653      * 
654      * @see <a
655      *      href="http://docs.mongodb.org/manual/reference/operator/meta/comment/">$comment</a>
656      */
657     public ConditionBuilder comment(final String comment) {
658         myParent.comment(comment);
659         return this;
660     }
661 
662     /**
663      * Query to match a single element in the array field.
664      * <p>
665      * Only a single {@link #elementMatches(DocumentAssignable)} comparison can
666      * be used. Calling multiple <tt>elementMatches(...)</tt> methods overwrites
667      * previous values. In addition any {@link #equals(boolean) equals(...)}
668      * condition is removed since no equality operator is supported by MongoDB.
669      * </p>
670      * 
671      * @param arrayElementQuery
672      *            A builder for the query to match a sub element. Any changes to
673      *            the {@link QueryBuilder} after this method is called are not
674      *            reflected in the comparison.
675      * @return The condition builder for chaining method calls.
676      */
677     public ConditionBuilder elementMatches(
678             final DocumentAssignable arrayElementQuery) {
679         myEqualsComparison = null;
680         myOtherComparisons.put(
681                 MiscellaneousOperator.ELEMENT_MATCH,
682                 new DocumentElement(MiscellaneousOperator.ELEMENT_MATCH
683                         .getToken(), arrayElementQuery.asDocument()));
684         return this;
685     }
686 
687     /**
688      * Checks if the value equals the specified <tt>value</tt>.
689      * <p>
690      * Only a single {@link #equals(boolean) equals(...)} comparison can be
691      * used. Calling multiple {@link #equals(byte[]) equals(...)} methods
692      * overwrites previous values. In addition <tt>equals(...)</tt> removes all
693      * other conditions from the builder since there is no equal operator
694      * supported by MongoDB.
695      * </p>
696      * 
697      * @param value
698      *            The value to compare the field against.
699      * @return The condition builder for chaining method calls.
700      */
701     public ConditionBuilder equals(final boolean value) {
702         myOtherComparisons.clear();
703         myEqualsComparison = new BooleanElement(getFieldName(), value);
704         return this;
705     }
706 
707     /**
708      * Checks if the value equals the specified <tt>value</tt>.
709      * <p>
710      * Only a single {@link #equals(boolean) equals(...)} comparison can be
711      * used. Calling multiple {@link #equals(byte[]) equals(...)} methods
712      * overwrites previous values. In addition <tt>equals(...)</tt> removes all
713      * other conditions from the builder since there is no equal operator
714      * supported by MongoDB.
715      * </p>
716      * 
717      * @param subType
718      *            The binary values subtype.
719      * @param value
720      *            The value to compare the field against.
721      * @return The condition builder for chaining method calls.
722      */
723     public ConditionBuilder equals(final byte subType, final byte[] value) {
724         myOtherComparisons.clear();
725         myEqualsComparison = new BinaryElement(getFieldName(), subType, value);
726         return this;
727     }
728 
729     /**
730      * Checks if the value equals the specified <tt>value</tt>.
731      * <p>
732      * Only a single {@link #equals(boolean) equals(...)} comparison can be
733      * used. Calling multiple {@link #equals(byte[]) equals(...)} methods
734      * overwrites previous values. In addition <tt>equals(...)</tt> removes all
735      * other conditions from the builder since there is no equal operator
736      * supported by MongoDB.
737      * </p>
738      * 
739      * @param value
740      *            The value to compare the field against.
741      * @return The condition builder for chaining method calls.
742      */
743     public ConditionBuilder equals(final byte[] value) {
744         myOtherComparisons.clear();
745         myEqualsComparison = new BinaryElement(getFieldName(), value);
746         return this;
747     }
748 
749     /**
750      * Checks if the value equals the specified <tt>dateTime</tt>.
751      * <p>
752      * This is equivalent to {@link #equalsTimestamp(long)
753      * equalsTimestamp(dateTime.getTime())}.
754      * </p>
755      * <p>
756      * Only a single {@link #equals(boolean) equals(...)} comparison can be
757      * used. Calling multiple {@link #equals(byte[]) equals(...)} methods
758      * overwrites previous values. In addition <tt>equals(...)</tt> removes all
759      * other conditions from the builder since there is no equal operator
760      * supported by MongoDB.
761      * </p>
762      * 
763      * @param dateTime
764      *            The value to compare the field against.
765      * @return The condition builder for chaining method calls.
766      * @see #equalsTimestamp(long)
767      */
768     public ConditionBuilder equals(final Date dateTime) {
769         return equalsTimestamp(dateTime.getTime());
770     }
771 
772     /**
773      * Checks if the value equals the specified <tt>value</tt>.
774      * <p>
775      * Only a single {@link #equals(boolean) equals(...)} comparison can be
776      * used. Calling multiple {@link #equals(byte[]) equals(...)} methods
777      * overwrites previous values. In addition <tt>equals(...)</tt> removes all
778      * other conditions from the builder since there is no equal operator
779      * supported by MongoDB.
780      * </p>
781      * 
782      * @param value
783      *            The value to compare the field against.
784      * @return The condition builder for chaining method calls.
785      */
786     public ConditionBuilder equals(final DocumentAssignable value) {
787         myOtherComparisons.clear();
788         myEqualsComparison = new DocumentElement(getFieldName(),
789                 value.asDocument());
790         return this;
791     }
792 
793     /**
794      * Checks if the value equals the specified <tt>value</tt>.
795      * <p>
796      * <b>NOTE:</b> Queries for matching a double value that closely
797      * approximates an integer value (e.g., 1.00) will compare equal to a stored
798      * integer or long value.
799      * </p>
800      * <p>
801      * Only a single {@link #equals(boolean) equals(...)} comparison can be
802      * used. Calling multiple {@link #equals(byte[]) equals(...)} methods
803      * overwrites previous values. In addition <tt>equals(...)</tt> removes all
804      * other conditions from the builder since there is no equal operator
805      * supported by MongoDB.
806      * </p>
807      * 
808      * @param value
809      *            The value to compare the field against.
810      * @return The condition builder for chaining method calls.
811      */
812     public ConditionBuilder equals(final double value) {
813         myOtherComparisons.clear();
814         myEqualsComparison = new DoubleElement(getFieldName(), value);
815         return this;
816     }
817 
818     /**
819      * Checks if the value equals the specified <tt>value</tt>.
820      * <p>
821      * <b>NOTE:</b> Queries for matching a integer value will compare equals to
822      * an equivalent stored long or closely matching double value.
823      * </p>
824      * <p>
825      * Only a single {@link #equals(boolean) equals(...)} comparison can be
826      * used. Calling multiple {@link #equals(byte[]) equals(...)} methods
827      * overwrites previous values. In addition <tt>equals(...)</tt> removes all
828      * other conditions from the builder since there is no equal operator
829      * supported by MongoDB.
830      * </p>
831      * 
832      * @param value
833      *            The value to compare the field against.
834      * @return The condition builder for chaining method calls.
835      */
836     public ConditionBuilder equals(final int value) {
837         myOtherComparisons.clear();
838         myEqualsComparison = new IntegerElement(getFieldName(), value);
839         return this;
840     }
841 
842     /**
843      * Checks if the value equals the specified <tt>value</tt>.
844      * <p>
845      * <b>NOTE:</b> Queries for matching a long value will compare equals to an
846      * equivalent stored integer or closely matching double value.
847      * </p>
848      * <p>
849      * Only a single {@link #equals(boolean) equals(...)} comparison can be
850      * used. Calling multiple {@link #equals(byte[]) equals(...)} methods
851      * overwrites previous values. In addition <tt>equals(...)</tt> removes all
852      * other conditions from the builder since there is no equal operator
853      * supported by MongoDB.
854      * </p>
855      * 
856      * @param value
857      *            The value to compare the field against.
858      * @return The condition builder for chaining method calls.
859      */
860     public ConditionBuilder equals(final long value) {
861         myOtherComparisons.clear();
862         myEqualsComparison = new LongElement(getFieldName(), value);
863         return this;
864     }
865 
866     /**
867      * Checks if the value equals the specified <tt>value</tt>.
868      * <p>
869      * Only a single {@link #equals(boolean) equals(...)} comparison can be
870      * used. Calling multiple {@link #equals(byte[]) equals(...)} methods
871      * overwrites previous values. In addition <tt>equals(...)</tt> removes all
872      * other conditions from the builder since there is no equal operator
873      * supported by MongoDB.
874      * </p>
875      * 
876      * @param value
877      *            The value to compare the field against.
878      * @return The condition builder for chaining method calls.
879      */
880     public ConditionBuilder equals(final ObjectId value) {
881         myOtherComparisons.clear();
882         myEqualsComparison = new ObjectIdElement(getFieldName(), value);
883         return this;
884     }
885 
886     /**
887      * Checks if the value equals the specified <tt>value</tt>.
888      * <p>
889      * <b>NOTE:</b> This checks if the value <b>is</b> a regular expression
890      * <b>or</b> if it is a string or symbol that matches the regular
891      * expression. It is functionally equivalent to {@link #matches(Pattern)}.
892      * </p>
893      * <p>
894      * Only a single {@link #equals(boolean) equals(...)} comparison can be
895      * used. Calling multiple {@link #equals(byte[]) equals(...)} methods
896      * overwrites previous values. In addition <tt>equals(...)</tt> removes all
897      * other conditions from the builder since there is no equal operator
898      * supported by MongoDB.
899      * </p>
900      * 
901      * @param value
902      *            The value to compare the field against.
903      * @return The condition builder for chaining method calls.
904      * 
905      * @see #matches(Pattern)
906      */
907     public ConditionBuilder equals(final Pattern value) {
908         myOtherComparisons.clear();
909         myEqualsComparison = new RegularExpressionElement(getFieldName(), value);
910         return this;
911     }
912 
913     /**
914      * Checks if the value equals the specified <tt>value</tt>.
915      * <p>
916      * <b>NOTE:</b> This method will match against a string or a symbol type
917      * element.
918      * </p>
919      * <p>
920      * Only a single {@link #equals(boolean) equals(...)} comparison can be
921      * used. Calling multiple {@link #equals(byte[]) equals(...)} methods
922      * overwrites previous values. In addition <tt>equals(...)</tt> removes all
923      * other conditions from the builder since there is no equal operator
924      * supported by MongoDB.
925      * </p>
926      * 
927      * @param value
928      *            The value to compare the field against.
929      * @return The condition builder for chaining method calls.
930      */
931     public ConditionBuilder equals(final String value) {
932         myOtherComparisons.clear();
933         myEqualsComparison = new StringElement(getFieldName(), value);
934         return this;
935     }
936 
937     /**
938      * Checks if the value equals the specified <tt>uuid</tt> using the standard
939      * byte ordering.
940      * <p>
941      * Only a single {@link #equals(boolean) equals(...)} comparison can be
942      * used. Calling multiple {@link #equals(byte[]) equals(...)} methods
943      * overwrites previous values. In addition <tt>equals(...)</tt> removes all
944      * other conditions from the builder since there is no equal operator
945      * supported by MongoDB.
946      * </p>
947      * 
948      * @param uuid
949      *            The value to compare the field against.
950      * @return The condition builder for chaining method calls.
951      */
952     public ConditionBuilder equals(final UUID uuid) {
953         myOtherComparisons.clear();
954         myEqualsComparison = new UuidElement(getFieldName(), uuid);
955         return this;
956     }
957 
958     /**
959      * Checks if the value equals the specified <tt>value</tt>.
960      * <p>
961      * Only a single {@link #equals(boolean) equals(...)} comparison can be
962      * used. Calling multiple {@link #equals(byte[]) equals(...)} methods
963      * overwrites previous values. In addition <tt>equals(...)</tt> removes all
964      * other conditions from the builder since there is no equal operator
965      * supported by MongoDB.
966      * </p>
967      * 
968      * @param value
969      *            The value to compare the field against.
970      * @return The condition builder for chaining method calls.
971      */
972     public ConditionBuilder equalsJavaScript(final String value) {
973         myOtherComparisons.clear();
974         myEqualsComparison = new JavaScriptElement(getFieldName(), value);
975         return this;
976     }
977 
978     /**
979      * Checks if the value equals the specified <tt>value</tt>.
980      * <p>
981      * <b>NOTE:</b> Testing has shown that the <tt>scope</tt> is ignored when
982      * performing the comparison.
983      * </p>
984      * <p>
985      * Only a single {@link #equals(boolean) equals(...)} comparison can be
986      * used. Calling multiple {@link #equals(byte[]) equals(...)} methods
987      * overwrites previous values. In addition <tt>equals(...)</tt> removes all
988      * other conditions from the builder since there is no equal operator
989      * supported by MongoDB.
990      * </p>
991      * 
992      * @param value
993      *            The value to compare the field against.
994      * @param scope
995      *            The stored scope value.
996      * @return The condition builder for chaining method calls.
997      */
998     public ConditionBuilder equalsJavaScript(final String value,
999             final DocumentAssignable scope) {
1000         myOtherComparisons.clear();
1001         myEqualsComparison = new JavaScriptWithScopeElement(getFieldName(),
1002                 value, scope.asDocument());
1003         return this;
1004     }
1005 
1006     /**
1007      * Checks if the value equals the specified <tt>value</tt> using the legacy
1008      * Java byte ordering.
1009      * <p>
1010      * Only a single {@link #equals(boolean) equals(...)} comparison can be
1011      * used. Calling multiple {@link #equals(byte[]) equals(...)} methods
1012      * overwrites previous values. In addition <tt>equals(...)</tt> removes all
1013      * other conditions from the builder since there is no equal operator
1014      * supported by MongoDB.
1015      * </p>
1016      * 
1017      * @param uuid
1018      *            The value to compare the field against.
1019      * @return The condition builder for chaining method calls.
1020      */
1021     public ConditionBuilder equalsLegacy(final UUID uuid) {
1022         myOtherComparisons.clear();
1023         myEqualsComparison = new UuidElement(getFieldName(),
1024                 UuidElement.LEGACY_UUID_SUBTTYPE, uuid);
1025         return this;
1026     }
1027 
1028     /**
1029      * Checks if the value is a max key element.
1030      * <p>
1031      * <b>WARNING:</b> Testing has shown that this query matches all documents
1032      * even if they do not contain any value for the field.
1033      * </p>
1034      * <p>
1035      * Only a single {@link #equals(boolean) equals(...)} comparison can be
1036      * used. Calling multiple {@link #equals(byte[]) equals(...)} methods
1037      * overwrites previous values. In addition <tt>equals(...)</tt> removes all
1038      * other conditions from the builder since there is no equal operator
1039      * supported by MongoDB.
1040      * </p>
1041      * 
1042      * @return The condition builder for chaining method calls.
1043      */
1044     public ConditionBuilder equalsMaxKey() {
1045         myOtherComparisons.clear();
1046         myEqualsComparison = new MaxKeyElement(getFieldName());
1047         return this;
1048     }
1049 
1050     /**
1051      * Checks if the value is a min key element.
1052      * <p>
1053      * <b>WARNING:</b> Testing has shown that this query matches all documents
1054      * even if they do not contain any value for the field.
1055      * </p>
1056      * <p>
1057      * Only a single {@link #equals(boolean) equals(...)} comparison can be
1058      * used. Calling multiple {@link #equals(byte[]) equals(...)} methods
1059      * overwrites previous values. In addition <tt>equals(...)</tt> removes all
1060      * other conditions from the builder since there is no equal operator
1061      * supported by MongoDB.
1062      * </p>
1063      * 
1064      * @return The condition builder for chaining method calls.
1065      */
1066     public ConditionBuilder equalsMinKey() {
1067         myOtherComparisons.clear();
1068         myEqualsComparison = new MinKeyElement(getFieldName());
1069         return this;
1070     }
1071 
1072     /**
1073      * Checks if the value equals the specified <tt>value</tt>.
1074      * <p>
1075      * <b>WARNING:</b> Testing has shown that this query will throw a
1076      * {@link QueryFailedException} if a document contains a field with the same
1077      * name but of type {@link ElementType#UTC_TIMESTAMP}.
1078      * </p>
1079      * <p>
1080      * Only a single {@link #equals(boolean) equals(...)} comparison can be
1081      * used. Calling multiple {@link #equals(byte[]) equals(...)} methods
1082      * overwrites previous values. In addition <tt>equals(...)</tt> removes all
1083      * other conditions from the builder since there is no equal operator
1084      * supported by MongoDB.
1085      * </p>
1086      * 
1087      * @param value
1088      *            The value to compare the field against.
1089      * @return The condition builder for chaining method calls.
1090      */
1091     public ConditionBuilder equalsMongoTimestamp(final long value) {
1092         myOtherComparisons.clear();
1093         myEqualsComparison = new MongoTimestampElement(getFieldName(), value);
1094         return this;
1095     }
1096 
1097     /**
1098      * Checks if the value is a null value.
1099      * <p>
1100      * <b>Note:</b> A field is considered to be <code>null</code> if it is a
1101      * literal <code>null</code> value in the document <b>OR</b> it does not
1102      * contain the field.
1103      * </p>
1104      * <p>
1105      * Only a single {@link #equals(boolean) equals(...)} comparison can be
1106      * used. Calling multiple {@link #equals(byte[]) equals(...)} methods
1107      * overwrites previous values. In addition <tt>equals(...)</tt> removes all
1108      * other conditions from the builder since there is no equal operator
1109      * supported by MongoDB.
1110      * </p>
1111      * 
1112      * @return The condition builder for chaining method calls.
1113      */
1114     public ConditionBuilder equalsNull() {
1115         myOtherComparisons.clear();
1116         myEqualsComparison = new NullElement(getFieldName());
1117         return this;
1118     }
1119 
1120     /**
1121      * Checks if the value equals the specified <tt>value</tt>.
1122      * <p>
1123      * Only a single {@link #equals(boolean) equals(...)} comparison can be
1124      * used. Calling multiple {@link #equals(byte[]) equals(...)} methods
1125      * overwrites previous values. In addition <tt>equals(...)</tt> removes all
1126      * other conditions from the builder since there is no equal operator
1127      * supported by MongoDB.
1128      * </p>
1129      * 
1130      * @param value
1131      *            The value to compare the field against.
1132      * @return The condition builder for chaining method calls.
1133      */
1134     public ConditionBuilder equalsSymbol(final String value) {
1135         myOtherComparisons.clear();
1136         myEqualsComparison = new SymbolElement(getFieldName(), value);
1137         return this;
1138     }
1139 
1140     /**
1141      * Checks if the value equals the specified <tt>value</tt>.
1142      * <p>
1143      * <b>NOTE:</b> Queries for matching a timestamp value will compare equals
1144      * to an equivalent stored MongoTimestamp value.
1145      * </p>
1146      * <p>
1147      * Only a single {@link #equals(boolean) equals(...)} comparison can be
1148      * used. Calling multiple {@link #equals(byte[]) equals(...)} methods
1149      * overwrites previous values. In addition <tt>equals(...)</tt> removes all
1150      * other conditions from the builder since there is no equal operator
1151      * supported by MongoDB.
1152      * </p>
1153      * 
1154      * @param value
1155      *            The value to compare the field against.
1156      * @return The condition builder for chaining method calls.
1157      */
1158     public ConditionBuilder equalsTimestamp(final long value) {
1159         myOtherComparisons.clear();
1160         myEqualsComparison = new TimestampElement(getFieldName(), value);
1161         return this;
1162     }
1163 
1164     /**
1165      * Checks if the field exists (or not) in the document.
1166      * <p>
1167      * Only a single {@link #exists(boolean) exists(...)} comparison can be
1168      * used. Calling multiple {@link #exists() exists(...)} methods overwrites
1169      * previous values. In addition any {@link #equals(boolean) equals(...)}
1170      * condition is removed since no equality operator is supported by MongoDB.
1171      * </p>
1172      * <p>
1173      * This method is equivalent to calling {@link #exists(boolean)
1174      * exists(true)}.
1175      * </p>
1176      * 
1177      * @return The condition builder for chaining method calls.
1178      */
1179     public ConditionBuilder exists() {
1180         return exists(true);
1181     }
1182 
1183     /**
1184      * Checks if the field exists (or not) in the document.
1185      * <p>
1186      * Only a single {@link #exists(boolean) exists(...)} comparison can be
1187      * used. Calling multiple {@link #exists() exists(...)} methods overwrites
1188      * previous values. In addition any {@link #equals(boolean) equals(...)}
1189      * condition is removed since no equality operator is supported by MongoDB.
1190      * </p>
1191      * 
1192      * @param value
1193      *            If true the field must exist. If false the field must not
1194      *            exist.
1195      * @return The condition builder for chaining method calls.
1196      */
1197     public ConditionBuilder exists(final boolean value) {
1198         myEqualsComparison = null;
1199         myOtherComparisons.put(MiscellaneousOperator.EXISTS,
1200                 new BooleanElement(MiscellaneousOperator.EXISTS.getToken(),
1201                         value));
1202         return this;
1203     }
1204 
1205     /**
1206      * Geospatial query for documents whose field intersects the specified
1207      * {@link GeoJson GeoJSON} specified geometry.
1208      * <p>
1209      * This method is designed to be use with a GeoJSON document constructed
1210      * with the {@link GeoJson} class<blockquote>
1211      * 
1212      * <pre>
1213      * <code>
1214      * {@link QueryBuilder#where where}("geo").intersects({@link GeoJson#lineString GeoJson.lineString}( {@link GeoJson#p GeoJson.p}(1,2),{@link GeoJson#p GeoJson.p}(10,11) ) );
1215      * </code>
1216      * </pre>
1217      * 
1218      * </blockquote>
1219      * </p>
1220      * <p>
1221      * <b>NOTE: </b> The {@code $geoIntersects} operator requires a
1222      * {@link Index#geo2dSphere(String) 2dsphere} index.
1223      * </p>
1224      * <p>
1225      * Only a single {@link #geoWithin} comparison can be used. Calling multiple
1226      * <tt>geoWithin(...)</tt> methods overwrites previous values. In addition
1227      * any {@link #equals(boolean) equals(...)} condition is removed since no
1228      * equality operator is supported by MongoDB.
1229      * </p>
1230      * 
1231      * @param geoJsonDoc
1232      *            The GeoJSON document describing the geometry.
1233      * @return The condition builder for chaining method calls.
1234      * 
1235      * @since MongoDB 2.4
1236      */
1237     public ConditionBuilder geoWithin(final DocumentAssignable geoJsonDoc) {
1238         myEqualsComparison = null;
1239 
1240         myOtherComparisons.put(GeospatialOperator.GEO_WITHIN,
1241                 new DocumentElement(GeospatialOperator.GEO_WITHIN.getToken(),
1242                         new DocumentElement(GeospatialOperator.GEOMETRY,
1243                                 geoJsonDoc.asDocument())));
1244 
1245         return this;
1246     }
1247 
1248     /**
1249      * Geospatial query for documents whose field intersects the specified
1250      * {@link GeoJson GeoJSON} specified geometry.
1251      * <p>
1252      * This method is designed to be use with a GeoJSON document constructed
1253      * with the {@link GeoJson} class<blockquote>
1254      * 
1255      * <pre>
1256      * <code>
1257      * {@link QueryBuilder#where where}("geo").intersects({@link GeoJson#lineString GeoJson.lineString}( {@link GeoJson#p GeoJson.p}(1,2),{@link GeoJson#p GeoJson.p}(10,11) ) );
1258      * </code>
1259      * </pre>
1260      * 
1261      * </blockquote>
1262      * </p>
1263      * <p>
1264      * <b>NOTE: </b> The {@code $geoIntersects} operator requires a
1265      * {@link Index#geo2dSphere(String) 2dsphere} index.
1266      * </p>
1267      * <p>
1268      * Only a single {@link #geoWithin} comparison can be used. Calling multiple
1269      * <tt>geoWithin(...)</tt> methods overwrites previous values. In addition
1270      * any {@link #equals(boolean) equals(...)} condition is removed since no
1271      * equality operator is supported by MongoDB.
1272      * </p>
1273      * 
1274      * @param geoJsonDoc
1275      *            The GeoJSON document describing the geometry.
1276      * @param unique
1277      *            If false then the query will return a document with multiple
1278      *            matching shaped or points multiple times.
1279      * @return The condition builder for chaining method calls.
1280      * 
1281      * @since MongoDB 2.4
1282      * @deprecated {@code $uniqueDocs} was removed in MongoDB 2.6. This method
1283      *             will not be removed until two releases after the MongoDB 2.6
1284      *             release (e.g. 2.10 if the releases are 2.8 and 2.10).
1285      */
1286     @Deprecated
1287     public ConditionBuilder geoWithin(final DocumentAssignable geoJsonDoc,
1288             final boolean unique) {
1289         myEqualsComparison = null;
1290 
1291         myOtherComparisons
1292                 .put(GeospatialOperator.GEO_WITHIN,
1293                         new DocumentElement(
1294                                 GeospatialOperator.GEO_WITHIN.getToken(),
1295                                 new DocumentElement(
1296                                         GeospatialOperator.GEOMETRY, geoJsonDoc
1297                                                 .asDocument()),
1298                                 new BooleanElement(
1299                                         GeospatialOperator.UNIQUE_DOCS_MODIFIER,
1300                                         unique)));
1301 
1302         return this;
1303     }
1304 
1305     /**
1306      * Returns the fieldName value.
1307      * 
1308      * @return The fieldName value.
1309      */
1310     public String getFieldName() {
1311         return myFieldName;
1312     }
1313 
1314     /**
1315      * Checks if the value is greater than the specified <tt>value</tt>.
1316      * <p>
1317      * Only a single {@link #greaterThan(int) greaterThan(...)} comparison can
1318      * be used. Calling multiple {@link #greaterThan(byte[]) greaterThan(...)}
1319      * methods overwrites previous values. In addition any
1320      * {@link #equals(boolean) equals(...)} condition is removed since no
1321      * equality operator is supported by MongoDB.
1322      * </p>
1323      * 
1324      * @param subType
1325      *            The binary values subtype.
1326      * @param value
1327      *            The value to compare the field against.
1328      * @return The condition builder for chaining method calls.
1329      */
1330     public ConditionBuilder greaterThan(final byte subType, final byte[] value) {
1331         myEqualsComparison = null;
1332         myOtherComparisons.put(ComparisonOperator.GT, new BinaryElement(
1333                 ComparisonOperator.GT.getToken(), subType, value));
1334         return this;
1335     }
1336 
1337     /**
1338      * Checks if the value is greater than the specified <tt>value</tt>.
1339      * <p>
1340      * Only a single {@link #greaterThan(int) greaterThan(...)} comparison can
1341      * be used. Calling multiple {@link #greaterThan(byte[]) greaterThan(...)}
1342      * methods overwrites previous values. In addition any
1343      * {@link #equals(boolean) equals(...)} condition is removed since no
1344      * equality operator is supported by MongoDB.
1345      * </p>
1346      * 
1347      * @param value
1348      *            The value to compare the field against.
1349      * @return The condition builder for chaining method calls.
1350      */
1351     public ConditionBuilder greaterThan(final byte[] value) {
1352         myEqualsComparison = null;
1353         myOtherComparisons.put(ComparisonOperator.GT, new BinaryElement(
1354                 ComparisonOperator.GT.getToken(), value));
1355         return this;
1356     }
1357 
1358     /**
1359      * Checks if the value is greater than the specified <tt>dateTime</tt>.
1360      * <p>
1361      * This is equivalent to {@link #greaterThanTimestamp(long)
1362      * greaterThanTimestamp(dateTime.getTime())}.
1363      * </p>
1364      * <p>
1365      * Only a single {@link #greaterThan(int) greaterThan(...)} comparison can
1366      * be used. Calling multiple {@link #greaterThan(byte[]) greaterThan(...)}
1367      * methods overwrites previous values. In addition any
1368      * {@link #equals(boolean) equals(...)} condition is removed since no
1369      * equality operator is supported by MongoDB.
1370      * </p>
1371      * 
1372      * @param dateTime
1373      *            The value to compare the field against.
1374      * @return The condition builder for chaining method calls.
1375      * @see #greaterThanTimestamp(long)
1376      */
1377     public ConditionBuilder greaterThan(final Date dateTime) {
1378         return greaterThanTimestamp(dateTime.getTime());
1379     }
1380 
1381     /**
1382      * Checks if the value is greater than the specified <tt>value</tt>.
1383      * <p>
1384      * Only a single {@link #greaterThan(int) greaterThan(...)} comparison can
1385      * be used. Calling multiple {@link #greaterThan(byte[]) greaterThan(...)}
1386      * methods overwrites previous values. In addition any
1387      * {@link #equals(boolean) equals(...)} condition is removed since no
1388      * equality operator is supported by MongoDB.
1389      * </p>
1390      * 
1391      * @param value
1392      *            The value to compare the field against.
1393      * @return The condition builder for chaining method calls.
1394      */
1395     public ConditionBuilder greaterThan(final double value) {
1396         myEqualsComparison = null;
1397         myOtherComparisons.put(ComparisonOperator.GT, new DoubleElement(
1398                 ComparisonOperator.GT.getToken(), value));
1399         return this;
1400     }
1401 
1402     /**
1403      * Checks if the value is greater than the specified <tt>value</tt>.
1404      * <p>
1405      * Only a single {@link #greaterThan(int) greaterThan(...)} comparison can
1406      * be used. Calling multiple {@link #greaterThan(byte[]) greaterThan(...)}
1407      * methods overwrites previous values. In addition any
1408      * {@link #equals(boolean) equals(...)} condition is removed since no
1409      * equality operator is supported by MongoDB.
1410      * </p>
1411      * 
1412      * @param value
1413      *            The value to compare the field against.
1414      * @return The condition builder for chaining method calls.
1415      */
1416     public ConditionBuilder greaterThan(final int value) {
1417         myEqualsComparison = null;
1418         myOtherComparisons.put(ComparisonOperator.GT, new IntegerElement(
1419                 ComparisonOperator.GT.getToken(), value));
1420         return this;
1421     }
1422 
1423     /**
1424      * Checks if the value is greater than the specified <tt>value</tt>.
1425      * <p>
1426      * Only a single {@link #greaterThan(int) greaterThan(...)} comparison can
1427      * be used. Calling multiple {@link #greaterThan(byte[]) greaterThan(...)}
1428      * methods overwrites previous values. In addition any
1429      * {@link #equals(boolean) equals(...)} condition is removed since no
1430      * equality operator is supported by MongoDB.
1431      * </p>
1432      * 
1433      * @param value
1434      *            The value to compare the field against.
1435      * @return The condition builder for chaining method calls.
1436      */
1437     public ConditionBuilder greaterThan(final long value) {
1438         myEqualsComparison = null;
1439         myOtherComparisons.put(ComparisonOperator.GT, new LongElement(
1440                 ComparisonOperator.GT.getToken(), value));
1441         return this;
1442     }
1443 
1444     /**
1445      * Checks if the value is greater than the specified <tt>value</tt>.
1446      * <p>
1447      * Only a single {@link #greaterThan(int) greaterThan(...)} comparison can
1448      * be used. Calling multiple {@link #greaterThan(byte[]) greaterThan(...)}
1449      * methods overwrites previous values. In addition any
1450      * {@link #equals(boolean) equals(...)} condition is removed since no
1451      * equality operator is supported by MongoDB.
1452      * </p>
1453      * 
1454      * @param value
1455      *            The value to compare the field against.
1456      * @return The condition builder for chaining method calls.
1457      */
1458     public ConditionBuilder greaterThan(final ObjectId value) {
1459         myEqualsComparison = null;
1460         myOtherComparisons.put(ComparisonOperator.GT, new ObjectIdElement(
1461                 ComparisonOperator.GT.getToken(), value));
1462         return this;
1463     }
1464 
1465     /**
1466      * Checks if the value is greater than the specified <tt>value</tt>.
1467      * <p>
1468      * Only a single {@link #greaterThan(int) greaterThan(...)} comparison can
1469      * be used. Calling multiple {@link #greaterThan(byte[]) greaterThan(...)}
1470      * methods overwrites previous values. In addition any
1471      * {@link #equals(boolean) equals(...)} condition is removed since no
1472      * equality operator is supported by MongoDB.
1473      * </p>
1474      * 
1475      * @param value
1476      *            The value to compare the field against.
1477      * @return The condition builder for chaining method calls.
1478      */
1479     public ConditionBuilder greaterThan(final String value) {
1480         myEqualsComparison = null;
1481         myOtherComparisons.put(ComparisonOperator.GT, new StringElement(
1482                 ComparisonOperator.GT.getToken(), value));
1483         return this;
1484     }
1485 
1486     /**
1487      * Checks if the value is greater than the specified <tt>value</tt>.
1488      * <p>
1489      * Only a single {@link #greaterThan(int) greaterThan(...)} comparison can
1490      * be used. Calling multiple {@link #greaterThan(byte[]) greaterThan(...)}
1491      * methods overwrites previous values. In addition any
1492      * {@link #equals(boolean) equals(...)} condition is removed since no
1493      * equality operator is supported by MongoDB.
1494      * </p>
1495      * 
1496      * @param value
1497      *            The value to compare the field against.
1498      * @return The condition builder for chaining method calls.
1499      */
1500     public ConditionBuilder greaterThanMongoTimestamp(final long value) {
1501         myEqualsComparison = null;
1502         myOtherComparisons.put(ComparisonOperator.GT,
1503                 new MongoTimestampElement(ComparisonOperator.GT.getToken(),
1504                         value));
1505         return this;
1506     }
1507 
1508     /**
1509      * Checks if the value is greater than or equals the specified
1510      * <tt>value</tt>.
1511      * <p>
1512      * Only a single {@link #greaterThanOrEqualTo(int)
1513      * greaterThanOrEqualTo(...)} comparison can be used. Calling multiple
1514      * {@link #greaterThanOrEqualTo(byte[]) greaterThanOrEqualTo(...)} methods
1515      * overwrites previous values. In addition any {@link #equals(boolean)
1516      * equals(...)} condition is removed since no equality operator is supported
1517      * by MongoDB.
1518      * </p>
1519      * 
1520      * @param subType
1521      *            The binary values subtype.
1522      * @param value
1523      *            The value to compare the field against.
1524      * @return The condition builder for chaining method calls.
1525      */
1526     public ConditionBuilder greaterThanOrEqualTo(final byte subType,
1527             final byte[] value) {
1528         myEqualsComparison = null;
1529         myOtherComparisons.put(ComparisonOperator.GTE, new BinaryElement(
1530                 ComparisonOperator.GTE.getToken(), subType, value));
1531         return this;
1532     }
1533 
1534     /**
1535      * Checks if the value is greater than or equals the specified
1536      * <tt>value</tt>.
1537      * <p>
1538      * Only a single {@link #greaterThanOrEqualTo(int)
1539      * greaterThanOrEqualTo(...)} comparison can be used. Calling multiple
1540      * {@link #greaterThanOrEqualTo(byte[]) greaterThanOrEqualTo(...)} methods
1541      * overwrites previous values. In addition any {@link #equals(boolean)
1542      * equals(...)} condition is removed since no equality operator is supported
1543      * by MongoDB.
1544      * </p>
1545      * 
1546      * @param value
1547      *            The value to compare the field against.
1548      * @return The condition builder for chaining method calls.
1549      */
1550     public ConditionBuilder greaterThanOrEqualTo(final byte[] value) {
1551         myEqualsComparison = null;
1552         myOtherComparisons.put(ComparisonOperator.GTE, new BinaryElement(
1553                 ComparisonOperator.GTE.getToken(), value));
1554         return this;
1555     }
1556 
1557     /**
1558      * Checks if the value is greater than or equals the specified
1559      * <tt>dateTime</tt>.
1560      * <p>
1561      * This is equivalent to {@link #greaterThanOrEqualToTimestamp(long)
1562      * greaterThanOrEqualToTimestamp(dateTime.getTime())}.
1563      * </p>
1564      * <p>
1565      * Only a single {@link #greaterThanOrEqualTo(int)
1566      * greaterThanOrEqualTo(...)} comparison can be used. Calling multiple
1567      * {@link #greaterThanOrEqualTo(byte[]) greaterThanOrEqualTo(...)} methods
1568      * overwrites previous values. In addition any {@link #equals(boolean)
1569      * equals(...)} condition is removed since no equality operator is supported
1570      * by MongoDB.
1571      * </p>
1572      * 
1573      * @param dateTime
1574      *            The value to compare the field against.
1575      * @return The condition builder for chaining method calls.
1576      * @see #greaterThanOrEqualToTimestamp(long)
1577      */
1578     public ConditionBuilder greaterThanOrEqualTo(final Date dateTime) {
1579         return greaterThanOrEqualToTimestamp(dateTime.getTime());
1580     }
1581 
1582     /**
1583      * Checks if the value is greater than or equals the specified
1584      * <tt>value</tt>.
1585      * <p>
1586      * Only a single {@link #greaterThanOrEqualTo(int)
1587      * greaterThanOrEqualTo(...)} comparison can be used. Calling multiple
1588      * {@link #greaterThanOrEqualTo(byte[]) greaterThanOrEqualTo(...)} methods
1589      * overwrites previous values. In addition any {@link #equals(boolean)
1590      * equals(...)} condition is removed since no equality operator is supported
1591      * by MongoDB.
1592      * </p>
1593      * 
1594      * @param value
1595      *            The value to compare the field against.
1596      * @return The condition builder for chaining method calls.
1597      */
1598     public ConditionBuilder greaterThanOrEqualTo(final double value) {
1599         myEqualsComparison = null;
1600         myOtherComparisons.put(ComparisonOperator.GTE, new DoubleElement(
1601                 ComparisonOperator.GTE.getToken(), value));
1602         return this;
1603     }
1604 
1605     /**
1606      * Checks if the value is greater than or equals the specified
1607      * <tt>value</tt>.
1608      * <p>
1609      * Only a single {@link #greaterThanOrEqualTo(int)
1610      * greaterThanOrEqualTo(...)} comparison can be used. Calling multiple
1611      * {@link #greaterThanOrEqualTo(byte[]) greaterThanOrEqualTo(...)} methods
1612      * overwrites previous values. In addition any {@link #equals(boolean)
1613      * equals(...)} condition is removed since no equality operator is supported
1614      * by MongoDB.
1615      * </p>
1616      * 
1617      * @param value
1618      *            The value to compare the field against.
1619      * @return The condition builder for chaining method calls.
1620      */
1621     public ConditionBuilder greaterThanOrEqualTo(final int value) {
1622         myEqualsComparison = null;
1623         myOtherComparisons.put(ComparisonOperator.GTE, new IntegerElement(
1624                 ComparisonOperator.GTE.getToken(), value));
1625         return this;
1626     }
1627 
1628     /**
1629      * Checks if the value is greater than or equals the specified
1630      * <tt>value</tt>.
1631      * <p>
1632      * Only a single {@link #greaterThanOrEqualTo(int)
1633      * greaterThanOrEqualTo(...)} comparison can be used. Calling multiple
1634      * {@link #greaterThanOrEqualTo(byte[]) greaterThanOrEqualTo(...)} methods
1635      * overwrites previous values. In addition any {@link #equals(boolean)
1636      * equals(...)} condition is removed since no equality operator is supported
1637      * by MongoDB.
1638      * </p>
1639      * 
1640      * @param value
1641      *            The value to compare the field against.
1642      * @return The condition builder for chaining method calls.
1643      */
1644     public ConditionBuilder greaterThanOrEqualTo(final long value) {
1645         myEqualsComparison = null;
1646         myOtherComparisons.put(ComparisonOperator.GTE, new LongElement(
1647                 ComparisonOperator.GTE.getToken(), value));
1648         return this;
1649     }
1650 
1651     /**
1652      * Checks if the value is greater than or equals the specified
1653      * <tt>value</tt>.
1654      * <p>
1655      * Only a single {@link #greaterThanOrEqualTo(int)
1656      * greaterThanOrEqualTo(...)} comparison can be used. Calling multiple
1657      * {@link #greaterThanOrEqualTo(byte[]) greaterThanOrEqualTo(...)} methods
1658      * overwrites previous values. In addition any {@link #equals(boolean)
1659      * equals(...)} condition is removed since no equality operator is supported
1660      * by MongoDB.
1661      * </p>
1662      * 
1663      * @param value
1664      *            The value to compare the field against.
1665      * @return The condition builder for chaining method calls.
1666      */
1667     public ConditionBuilder greaterThanOrEqualTo(final ObjectId value) {
1668         myEqualsComparison = null;
1669         myOtherComparisons.put(ComparisonOperator.GTE, new ObjectIdElement(
1670                 ComparisonOperator.GTE.getToken(), value));
1671         return this;
1672     }
1673 
1674     /**
1675      * Checks if the value is greater than or equals the specified
1676      * <tt>value</tt>.
1677      * <p>
1678      * Only a single {@link #greaterThanOrEqualTo(int)
1679      * greaterThanOrEqualTo(...)} comparison can be used. Calling multiple
1680      * {@link #greaterThanOrEqualTo(byte[]) greaterThanOrEqualTo(...)} methods
1681      * overwrites previous values. In addition any {@link #equals(boolean)
1682      * equals(...)} condition is removed since no equality operator is supported
1683      * by MongoDB.
1684      * </p>
1685      * 
1686      * @param value
1687      *            The value to compare the field against.
1688      * @return The condition builder for chaining method calls.
1689      */
1690     public ConditionBuilder greaterThanOrEqualTo(final String value) {
1691         myEqualsComparison = null;
1692         myOtherComparisons.put(ComparisonOperator.GTE, new StringElement(
1693                 ComparisonOperator.GTE.getToken(), value));
1694         return this;
1695     }
1696 
1697     /**
1698      * Checks if the value is greater than or equals the specified
1699      * <tt>value</tt>.
1700      * <p>
1701      * Only a single {@link #greaterThanOrEqualTo(int)
1702      * greaterThanOrEqualTo(...)} comparison can be used. Calling multiple
1703      * {@link #greaterThanOrEqualTo(byte[]) greaterThanOrEqualTo(...)} methods
1704      * overwrites previous values. In addition any {@link #equals(boolean)
1705      * equals(...)} condition is removed since no equality operator is supported
1706      * by MongoDB.
1707      * </p>
1708      * 
1709      * @param value
1710      *            The value to compare the field against.
1711      * @return The condition builder for chaining method calls.
1712      */
1713     public ConditionBuilder greaterThanOrEqualToMongoTimestamp(final long value) {
1714         myEqualsComparison = null;
1715         myOtherComparisons.put(ComparisonOperator.GTE,
1716                 new MongoTimestampElement(ComparisonOperator.GTE.getToken(),
1717                         value));
1718         return this;
1719     }
1720 
1721     /**
1722      * Checks if the value is greater than or equals the specified
1723      * <tt>value</tt>.
1724      * <p>
1725      * Only a single {@link #greaterThanOrEqualTo(int)
1726      * greaterThanOrEqualTo(...)} comparison can be used. Calling multiple
1727      * {@link #greaterThanOrEqualTo(byte[]) greaterThanOrEqualTo(...)} methods
1728      * overwrites previous values. In addition any {@link #equals(boolean)
1729      * equals(...)} condition is removed since no equality operator is supported
1730      * by MongoDB.
1731      * </p>
1732      * 
1733      * @param value
1734      *            The value to compare the field against.
1735      * @return The condition builder for chaining method calls.
1736      */
1737     public ConditionBuilder greaterThanOrEqualToSymbol(final String value) {
1738         myEqualsComparison = null;
1739         myOtherComparisons.put(ComparisonOperator.GTE, new SymbolElement(
1740                 ComparisonOperator.GTE.getToken(), value));
1741         return this;
1742     }
1743 
1744     /**
1745      * Checks if the value is greater than or equals the specified
1746      * <tt>value</tt>.
1747      * <p>
1748      * Only a single {@link #greaterThanOrEqualTo(int)
1749      * greaterThanOrEqualTo(...)} comparison can be used. Calling multiple
1750      * {@link #greaterThanOrEqualTo(byte[]) greaterThanOrEqualTo(...)} methods
1751      * overwrites previous values. In addition any {@link #equals(boolean)
1752      * equals(...)} condition is removed since no equality operator is supported
1753      * by MongoDB.
1754      * </p>
1755      * 
1756      * @param value
1757      *            The value to compare the field against.
1758      * @return The condition builder for chaining method calls.
1759      */
1760     public ConditionBuilder greaterThanOrEqualToTimestamp(final long value) {
1761         myEqualsComparison = null;
1762         myOtherComparisons.put(ComparisonOperator.GTE, new TimestampElement(
1763                 ComparisonOperator.GTE.getToken(), value));
1764         return this;
1765     }
1766 
1767     /**
1768      * Checks if the value is greater than the specified <tt>value</tt>.
1769      * <p>
1770      * Only a single {@link #greaterThan(int) greaterThan(...)} comparison can
1771      * be used. Calling multiple {@link #greaterThan(byte[]) greaterThan(...)}
1772      * methods overwrites previous values. In addition any
1773      * {@link #equals(boolean) equals(...)} condition is removed since no
1774      * equality operator is supported by MongoDB.
1775      * </p>
1776      * 
1777      * @param value
1778      *            The value to compare the field against.
1779      * @return The condition builder for chaining method calls.
1780      */
1781     public ConditionBuilder greaterThanSymbol(final String value) {
1782         myEqualsComparison = null;
1783         myOtherComparisons.put(ComparisonOperator.GT, new SymbolElement(
1784                 ComparisonOperator.GT.getToken(), value));
1785         return this;
1786     }
1787 
1788     /**
1789      * Checks if the value is greater than the specified <tt>value</tt>.
1790      * <p>
1791      * Only a single {@link #greaterThan(int) greaterThan(...)} comparison can
1792      * be used. Calling multiple {@link #greaterThan(byte[]) greaterThan(...)}
1793      * methods overwrites previous values. In addition any
1794      * {@link #equals(boolean) equals(...)} condition is removed since no
1795      * equality operator is supported by MongoDB.
1796      * </p>
1797      * 
1798      * @param value
1799      *            The value to compare the field against.
1800      * @return The condition builder for chaining method calls.
1801      */
1802     public ConditionBuilder greaterThanTimestamp(final long value) {
1803         myEqualsComparison = null;
1804         myOtherComparisons.put(ComparisonOperator.GT, new TimestampElement(
1805                 ComparisonOperator.GT.getToken(), value));
1806         return this;
1807     }
1808 
1809     /**
1810      * Specify the possible values to match against the field's value.
1811      * <p>
1812      * Only a single {@link #in(ArrayBuilder)} comparison can be used. Calling
1813      * multiple <tt>in(...)</tt> methods overwrites previous values. In addition
1814      * any {@link #equals(boolean) equals(...)} condition is removed since no
1815      * equality operator is supported by MongoDB.
1816      * </p>
1817      * 
1818      * @param elements
1819      *            A builder for the values for the comparison. Any changes to
1820      *            the {@link ArrayBuilder} after this method is called are not
1821      *            reflected in the comparison.
1822      * @return The condition builder for chaining method calls.
1823      */
1824     public ConditionBuilder in(final ArrayBuilder elements) {
1825         return in(elements.build());
1826     }
1827 
1828     /**
1829      * Specify the possible values to match against the field's value. Atleast
1830      * one of the
1831      * <p>
1832      * This method can only be used with values of the same BSON type. If mixed
1833      * types need to be used there are several options:
1834      * <ul>
1835      * <li>Use the {@link Expressions#constant Expressions#constant(...)}
1836      * helpers with the {@link #in(Constant...)} method.</li>
1837      * <li>Use the {@link ArrayBuilder} with the {@link #in(ArrayBuilder)}
1838      * method.</li>
1839      * <li>Manually construct the {@link Element elements} and use the
1840      * {@link #in(Element...)} method.</li>
1841      * </ul>
1842      * </p>
1843      * <p>
1844      * Only a single {@link #in(Element[])} comparison can be used. Calling
1845      * multiple <tt>in(...)</tt> methods overwrites previous values. In addition
1846      * any {@link #equals(boolean) equals(...)} condition is removed since no
1847      * equality operator is supported by MongoDB.
1848      * </p>
1849      * 
1850      * @param values
1851      *            The values for the comparison.
1852      * @return The condition builder for chaining method calls.
1853      */
1854     public ConditionBuilder in(final boolean... values) {
1855         final ArrayBuilder arrayBuilder = BuilderFactory.startArray();
1856         for (final boolean value : values) {
1857             arrayBuilder.add(value);
1858         }
1859         return in(arrayBuilder);
1860     }
1861 
1862     /**
1863      * Specify the possible values to match against the field's value. Atleast
1864      * one of the
1865      * <p>
1866      * This method can only be used with values of the same BSON type. If mixed
1867      * types need to be used there are several options:
1868      * <ul>
1869      * <li>Use the {@link Expressions#constant Expressions#constant(...)}
1870      * helpers with the {@link #in(Constant...)} method.</li>
1871      * <li>Use the {@link ArrayBuilder} with the {@link #in(ArrayBuilder)}
1872      * method.</li>
1873      * <li>Manually construct the {@link Element elements} and use the
1874      * {@link #in(Element...)} method.</li>
1875      * </ul>
1876      * </p>
1877      * <p>
1878      * Only a single {@link #in(Element[])} comparison can be used. Calling
1879      * multiple <tt>in(...)</tt> methods overwrites previous values. In addition
1880      * any {@link #equals(boolean) equals(...)} condition is removed since no
1881      * equality operator is supported by MongoDB.
1882      * </p>
1883      * 
1884      * @param values
1885      *            The values for the comparison.
1886      * @return The condition builder for chaining method calls.
1887      */
1888     public ConditionBuilder in(final byte[]... values) {
1889         final ArrayBuilder arrayBuilder = BuilderFactory.startArray();
1890         for (final byte[] value : values) {
1891             arrayBuilder.add(value);
1892         }
1893         return in(arrayBuilder);
1894     }
1895 
1896     /**
1897      * Specify the possible values to match against the field's value.
1898      * <p>
1899      * This method is designed to be used with the {@link Expressions#constant
1900      * Expressions.constant(...)} helper methods.<blockquote>
1901      * 
1902      * <pre>
1903      * <code>
1904      * import static {@link Expressions#constant com.allanbank.mongodb.builder.expression.Expressions.constant};
1905      * 
1906      * DocumentAssignable query = QueryBuilder.where("f").in(constant(1), constant(2), constant(3));
1907      * </code>
1908      * </pre>
1909      * 
1910      * </blockquote>
1911      * </p>
1912      * <p>
1913      * Only a single {@link #in(Element[])} comparison can be used. Calling
1914      * multiple <tt>in(...)</tt> methods overwrites previous values. In addition
1915      * any {@link #equals(boolean) equals(...)} condition is removed since no
1916      * equality operator is supported by MongoDB.
1917      * </p>
1918      * 
1919      * @param values
1920      *            The values for the comparison.
1921      * @return The condition builder for chaining method calls.
1922      */
1923     public ConditionBuilder in(final Constant... values) {
1924         myEqualsComparison = null;
1925 
1926         final List<Element> elements = new ArrayList<Element>(values.length);
1927         for (int i = 0; i < values.length; ++i) {
1928             elements.add(values[i].toElement(ArrayElement.nameFor(i)));
1929         }
1930         myOtherComparisons.put(MiscellaneousOperator.IN, new ArrayElement(
1931                 MiscellaneousOperator.IN.getToken(), elements));
1932 
1933         return this;
1934     }
1935 
1936     /**
1937      * Specify the possible values to match against the field's value. Atleast
1938      * one of the
1939      * <p>
1940      * This method can only be used with values of the same BSON type. If mixed
1941      * types need to be used there are several options:
1942      * <ul>
1943      * <li>Use the {@link Expressions#constant Expressions#constant(...)}
1944      * helpers with the {@link #in(Constant...)} method.</li>
1945      * <li>Use the {@link ArrayBuilder} with the {@link #in(ArrayBuilder)}
1946      * method.</li>
1947      * <li>Manually construct the {@link Element elements} and use the
1948      * {@link #in(Element...)} method.</li>
1949      * </ul>
1950      * </p>
1951      * <p>
1952      * Only a single {@link #in(Element[])} comparison can be used. Calling
1953      * multiple <tt>in(...)</tt> methods overwrites previous values. In addition
1954      * any {@link #equals(boolean) equals(...)} condition is removed since no
1955      * equality operator is supported by MongoDB.
1956      * </p>
1957      * 
1958      * @param values
1959      *            The values for the comparison.
1960      * @return The condition builder for chaining method calls.
1961      */
1962     public ConditionBuilder in(final Date... values) {
1963         final ArrayBuilder arrayBuilder = BuilderFactory.startArray();
1964         for (final Date value : values) {
1965             arrayBuilder.add(value);
1966         }
1967         return in(arrayBuilder);
1968     }
1969 
1970     /**
1971      * Specify the possible values to match against the field's value. Atleast
1972      * one of the
1973      * <p>
1974      * This method can only be used with values of the same BSON type. If mixed
1975      * types need to be used there are several options:
1976      * <ul>
1977      * <li>Use the {@link Expressions#constant Expressions#constant(...)}
1978      * helpers with the {@link #in(Constant...)} method.</li>
1979      * <li>Use the {@link ArrayBuilder} with the {@link #in(ArrayBuilder)}
1980      * method.</li>
1981      * <li>Manually construct the {@link Element elements} and use the
1982      * {@link #in(Element...)} method.</li>
1983      * </ul>
1984      * </p>
1985      * <p>
1986      * Only a single {@link #in(Element[])} comparison can be used. Calling
1987      * multiple <tt>in(...)</tt> methods overwrites previous values. In addition
1988      * any {@link #equals(boolean) equals(...)} condition is removed since no
1989      * equality operator is supported by MongoDB.
1990      * </p>
1991      * 
1992      * @param values
1993      *            The values for the comparison.
1994      * @return The condition builder for chaining method calls.
1995      */
1996     public ConditionBuilder in(final DocumentAssignable... values) {
1997         final ArrayBuilder arrayBuilder = BuilderFactory.startArray();
1998         for (final DocumentAssignable value : values) {
1999             arrayBuilder.add(value);
2000         }
2001         return in(arrayBuilder);
2002     }
2003 
2004     /**
2005      * Specify the possible values to match against the field's value. Atleast
2006      * one of the
2007      * <p>
2008      * This method can only be used with values of the same BSON type. If mixed
2009      * types need to be used there are several options:
2010      * <ul>
2011      * <li>Use the {@link Expressions#constant Expressions#constant(...)}
2012      * helpers with the {@link #in(Constant...)} method.</li>
2013      * <li>Use the {@link ArrayBuilder} with the {@link #in(ArrayBuilder)}
2014      * method.</li>
2015      * <li>Manually construct the {@link Element elements} and use the
2016      * {@link #in(Element...)} method.</li>
2017      * </ul>
2018      * </p>
2019      * <p>
2020      * Only a single {@link #in(Element[])} comparison can be used. Calling
2021      * multiple <tt>in(...)</tt> methods overwrites previous values. In addition
2022      * any {@link #equals(boolean) equals(...)} condition is removed since no
2023      * equality operator is supported by MongoDB.
2024      * </p>
2025      * 
2026      * @param values
2027      *            The values for the comparison.
2028      * @return The condition builder for chaining method calls.
2029      */
2030     public ConditionBuilder in(final Double... values) {
2031         final ArrayBuilder arrayBuilder = BuilderFactory.startArray();
2032         for (final Double value : values) {
2033             arrayBuilder.add(value.doubleValue());
2034         }
2035         return in(arrayBuilder);
2036     }
2037 
2038     /**
2039      * Specify the possible values to match against the field's value.
2040      * <p>
2041      * Only a single {@link #in(Element[])} comparison can be used. Calling
2042      * multiple <tt>in(...)</tt> methods overwrites previous values. In addition
2043      * any {@link #equals(boolean) equals(...)} condition is removed since no
2044      * equality operator is supported by MongoDB.
2045      * </p>
2046      * 
2047      * @param elements
2048      *            The element values for the comparison.
2049      * @return The condition builder for chaining method calls.
2050      */
2051     public ConditionBuilder in(final Element... elements) {
2052         myEqualsComparison = null;
2053         myOtherComparisons.put(MiscellaneousOperator.IN, new ArrayElement(
2054                 MiscellaneousOperator.IN.getToken(), elements));
2055 
2056         return this;
2057     }
2058 
2059     /**
2060      * Specify the possible values to match against the field's value. Atleast
2061      * one of the
2062      * <p>
2063      * This method can only be used with values of the same BSON type. If mixed
2064      * types need to be used there are several options:
2065      * <ul>
2066      * <li>Use the {@link Expressions#constant Expressions#constant(...)}
2067      * helpers with the {@link #in(Constant...)} method.</li>
2068      * <li>Use the {@link ArrayBuilder} with the {@link #in(ArrayBuilder)}
2069      * method.</li>
2070      * <li>Manually construct the {@link Element elements} and use the
2071      * {@link #in(Element...)} method.</li>
2072      * </ul>
2073      * </p>
2074      * <p>
2075      * Only a single {@link #in(Element[])} comparison can be used. Calling
2076      * multiple <tt>in(...)</tt> methods overwrites previous values. In addition
2077      * any {@link #equals(boolean) equals(...)} condition is removed since no
2078      * equality operator is supported by MongoDB.
2079      * </p>
2080      * 
2081      * @param values
2082      *            The values for the comparison.
2083      * @return The condition builder for chaining method calls.
2084      */
2085     public ConditionBuilder in(final Integer... values) {
2086         final ArrayBuilder arrayBuilder = BuilderFactory.startArray();
2087         for (final Integer value : values) {
2088             arrayBuilder.add(value.intValue());
2089         }
2090         return in(arrayBuilder);
2091     }
2092 
2093     /**
2094      * Specify the possible values to match against the field's value. Atleast
2095      * one of the
2096      * <p>
2097      * This method can only be used with values of the same BSON type. If mixed
2098      * types need to be used there are several options:
2099      * <ul>
2100      * <li>Use the {@link Expressions#constant Expressions#constant(...)}
2101      * helpers with the {@link #in(Constant...)} method.</li>
2102      * <li>Use the {@link ArrayBuilder} with the {@link #in(ArrayBuilder)}
2103      * method.</li>
2104      * <li>Manually construct the {@link Element elements} and use the
2105      * {@link #in(Element...)} method.</li>
2106      * </ul>
2107      * </p>
2108      * <p>
2109      * Only a single {@link #in(Element[])} comparison can be used. Calling
2110      * multiple <tt>in(...)</tt> methods overwrites previous values. In addition
2111      * any {@link #equals(boolean) equals(...)} condition is removed since no
2112      * equality operator is supported by MongoDB.
2113      * </p>
2114      * 
2115      * @param values
2116      *            The values for the comparison.
2117      * @return The condition builder for chaining method calls.
2118      */
2119     public ConditionBuilder in(final Long... values) {
2120         final ArrayBuilder arrayBuilder = BuilderFactory.startArray();
2121         for (final Long value : values) {
2122             arrayBuilder.add(value.longValue());
2123         }
2124         return in(arrayBuilder);
2125     }
2126 
2127     /**
2128      * Specify the possible values to match against the field's value. Atleast
2129      * one of the
2130      * <p>
2131      * This method can only be used with values of the same BSON type. If mixed
2132      * types need to be used there are several options:
2133      * <ul>
2134      * <li>Use the {@link Expressions#constant Expressions#constant(...)}
2135      * helpers with the {@link #in(Constant...)} method.</li>
2136      * <li>Use the {@link ArrayBuilder} with the {@link #in(ArrayBuilder)}
2137      * method.</li>
2138      * <li>Manually construct the {@link Element elements} and use the
2139      * {@link #in(Element...)} method.</li>
2140      * </ul>
2141      * </p>
2142      * <p>
2143      * Only a single {@link #in(Element[])} comparison can be used. Calling
2144      * multiple <tt>in(...)</tt> methods overwrites previous values. In addition
2145      * any {@link #equals(boolean) equals(...)} condition is removed since no
2146      * equality operator is supported by MongoDB.
2147      * </p>
2148      * 
2149      * @param values
2150      *            The values for the comparison.
2151      * @return The condition builder for chaining method calls.
2152      */
2153     public ConditionBuilder in(final ObjectId... values) {
2154         final ArrayBuilder arrayBuilder = BuilderFactory.startArray();
2155         for (final ObjectId value : values) {
2156             arrayBuilder.add(value);
2157         }
2158         return in(arrayBuilder);
2159     }
2160 
2161     /**
2162      * Specify the possible values to match against the field's value. Atleast
2163      * one of the
2164      * <p>
2165      * This method can only be used with values of the same BSON type. If mixed
2166      * types need to be used there are several options:
2167      * <ul>
2168      * <li>Use the {@link Expressions#constant Expressions#constant(...)}
2169      * helpers with the {@link #in(Constant...)} method.</li>
2170      * <li>Use the {@link ArrayBuilder} with the {@link #in(ArrayBuilder)}
2171      * method.</li>
2172      * <li>Manually construct the {@link Element elements} and use the
2173      * {@link #in(Element...)} method.</li>
2174      * </ul>
2175      * </p>
2176      * <p>
2177      * Only a single {@link #in(Element[])} comparison can be used. Calling
2178      * multiple <tt>in(...)</tt> methods overwrites previous values. In addition
2179      * any {@link #equals(boolean) equals(...)} condition is removed since no
2180      * equality operator is supported by MongoDB.
2181      * </p>
2182      * 
2183      * @param values
2184      *            The values for the comparison.
2185      * @return The condition builder for chaining method calls.
2186      */
2187     public ConditionBuilder in(final Pattern... values) {
2188         final ArrayBuilder arrayBuilder = BuilderFactory.startArray();
2189         for (final Pattern value : values) {
2190             arrayBuilder.add(value);
2191         }
2192         return in(arrayBuilder);
2193     }
2194 
2195     /**
2196      * Specify the possible values to match against the field's value. Atleast
2197      * one of the
2198      * <p>
2199      * This method can only be used with values of the same BSON type. If mixed
2200      * types need to be used there are several options:
2201      * <ul>
2202      * <li>Use the {@link Expressions#constant Expressions#constant(...)}
2203      * helpers with the {@link #in(Constant...)} method.</li>
2204      * <li>Use the {@link ArrayBuilder} with the {@link #in(ArrayBuilder)}
2205      * method.</li>
2206      * <li>Manually construct the {@link Element elements} and use the
2207      * {@link #in(Element...)} method.</li>
2208      * </ul>
2209      * </p>
2210      * <p>
2211      * Only a single {@link #in(Element[])} comparison can be used. Calling
2212      * multiple <tt>in(...)</tt> methods overwrites previous values. In addition
2213      * any {@link #equals(boolean) equals(...)} condition is removed since no
2214      * equality operator is supported by MongoDB.
2215      * </p>
2216      * 
2217      * @param values
2218      *            The values for the comparison.
2219      * @return The condition builder for chaining method calls.
2220      */
2221     public ConditionBuilder in(final String... values) {
2222         final ArrayBuilder arrayBuilder = BuilderFactory.startArray();
2223         for (final String value : values) {
2224             arrayBuilder.add(value);
2225         }
2226         return in(arrayBuilder);
2227     }
2228 
2229     /**
2230      * Specify the possible values to match against the field's value. Atleast
2231      * one of the
2232      * <p>
2233      * This method can only be used with values of the same BSON type. If mixed
2234      * types need to be used there are several options:
2235      * <ul>
2236      * <li>Use the {@link Expressions#constant Expressions#constant(...)}
2237      * helpers with the {@link #in(Constant...)} method.</li>
2238      * <li>Use the {@link ArrayBuilder} with the {@link #in(ArrayBuilder)}
2239      * method.</li>
2240      * <li>Manually construct the {@link Element elements} and use the
2241      * {@link #in(Element...)} method.</li>
2242      * </ul>
2243      * </p>
2244      * <p>
2245      * Only a single {@link #in(Element[])} comparison can be used. Calling
2246      * multiple <tt>in(...)</tt> methods overwrites previous values. In addition
2247      * any {@link #equals(boolean) equals(...)} condition is removed since no
2248      * equality operator is supported by MongoDB.
2249      * </p>
2250      * 
2251      * @param values
2252      *            The values for the comparison.
2253      * @return The condition builder for chaining method calls.
2254      */
2255     public ConditionBuilder in(final UUID... values) {
2256         final ArrayBuilder arrayBuilder = BuilderFactory.startArray();
2257         for (final UUID value : values) {
2258             arrayBuilder.add(value);
2259         }
2260         return in(arrayBuilder);
2261     }
2262 
2263     /**
2264      * Checks if the value's type matches the specified <tt>type</tt>.
2265      * <p>
2266      * Only a single {@link #instanceOf(ElementType)} comparison can be used.
2267      * Calling multiple {@link #instanceOf(ElementType)} methods overwrites
2268      * previous values. In addition any {@link #equals(boolean) equals(...)}
2269      * condition is removed since no equality operator is supported by MongoDB.
2270      * </p>
2271      * 
2272      * @param type
2273      *            The expected type for the value.
2274      * 
2275      * @return The condition builder for chaining method calls.
2276      */
2277     public ConditionBuilder instanceOf(final ElementType type) {
2278         myEqualsComparison = null;
2279         myOtherComparisons.put(MiscellaneousOperator.TYPE, new IntegerElement(
2280                 MiscellaneousOperator.TYPE.getToken(), type.getToken()));
2281         return this;
2282     }
2283 
2284     /**
2285      * Geospatial query for documents whose field intersects the specified
2286      * {@link GeoJson GeoJSON} specified geometry.
2287      * <p>
2288      * This method is designed to be use with a GeoJSON document constructed
2289      * with the {@link GeoJson} class<blockquote>
2290      * 
2291      * <pre>
2292      * <code>
2293      * {@link QueryBuilder#where where}("geo").intersects({@link GeoJson#lineString GeoJson.lineString}( {@link GeoJson#p GeoJson.p}(1,2),{@link GeoJson#p GeoJson.p}(10,11) ) );
2294      * </code>
2295      * </pre>
2296      * 
2297      * </blockquote>
2298      * </p>
2299      * <p>
2300      * <b>NOTE: </b> The {@code $geoIntersects} operator requires a
2301      * {@link Index#geo2dSphere(String) 2dsphere} index.
2302      * </p>
2303      * <p>
2304      * Only a single {@link #intersects} comparison can be used. Calling
2305      * multiple <tt>intersects(...)</tt> methods overwrites previous values. In
2306      * addition any {@link #equals(boolean) equals(...)} condition is removed
2307      * since no equality operator is supported by MongoDB.
2308      * </p>
2309      * 
2310      * @param geoJsonDoc
2311      *            The GeoJSON document describing the geometry.
2312      * @return The condition builder for chaining method calls.
2313      * 
2314      * @since MongoDB 2.4
2315      */
2316     public ConditionBuilder intersects(final DocumentAssignable geoJsonDoc) {
2317         myEqualsComparison = null;
2318 
2319         myOtherComparisons.put(GeospatialOperator.INTERSECT,
2320                 new DocumentElement(GeospatialOperator.INTERSECT.getToken(),
2321                         new DocumentElement(GeospatialOperator.GEOMETRY,
2322                                 geoJsonDoc.asDocument())));
2323 
2324         return this;
2325     }
2326 
2327     /**
2328      * Checks if the value is less than the specified <tt>value</tt>.
2329      * <p>
2330      * Only a single {@link #lessThan(int) lessThan(...)} comparison can be
2331      * used. Calling multiple {@link #lessThan(byte[]) lessThan(...)} methods
2332      * overwrites previous values. In addition any {@link #equals(boolean)
2333      * equals(...)} condition is removed since no equality operator is supported
2334      * by MongoDB.
2335      * </p>
2336      * 
2337      * @param subType
2338      *            The binary values subtype.
2339      * @param value
2340      *            The value to compare the field against.
2341      * @return The condition builder for chaining method calls.
2342      */
2343     public ConditionBuilder lessThan(final byte subType, final byte[] value) {
2344         myEqualsComparison = null;
2345         myOtherComparisons.put(ComparisonOperator.LT, new BinaryElement(
2346                 ComparisonOperator.LT.getToken(), subType, value));
2347         return this;
2348     }
2349 
2350     /**
2351      * Checks if the value is less than the specified <tt>value</tt>.
2352      * <p>
2353      * Only a single {@link #lessThan(int) lessThan(...)} comparison can be
2354      * used. Calling multiple {@link #lessThan(byte[]) lessThan(...)} methods
2355      * overwrites previous values. In addition any {@link #equals(boolean)
2356      * equals(...)} condition is removed since no equality operator is supported
2357      * by MongoDB.
2358      * </p>
2359      * 
2360      * @param value
2361      *            The value to compare the field against.
2362      * @return The condition builder for chaining method calls.
2363      */
2364     public ConditionBuilder lessThan(final byte[] value) {
2365         myEqualsComparison = null;
2366         myOtherComparisons.put(ComparisonOperator.LT, new BinaryElement(
2367                 ComparisonOperator.LT.getToken(), value));
2368         return this;
2369     }
2370 
2371     /**
2372      * Checks if the value is less than the specified <tt>dateTime</tt>.
2373      * <p>
2374      * This is equivalent to {@link #lessThanTimestamp(long)
2375      * lessThanTimestamp(dateTime.getTime())}.
2376      * </p>
2377      * <p>
2378      * Only a single {@link #lessThan(int) lessThan(...)} comparison can be
2379      * used. Calling multiple {@link #lessThan(byte[]) lessThan(...)} methods
2380      * overwrites previous values. In addition any {@link #equals(boolean)
2381      * equals(...)} condition is removed since no equality operator is supported
2382      * by MongoDB.
2383      * </p>
2384      * 
2385      * @param dateTime
2386      *            The value to compare the field against.
2387      * @return The condition builder for chaining method calls.
2388      * @see #lessThanTimestamp(long)
2389      */
2390     public ConditionBuilder lessThan(final Date dateTime) {
2391         return lessThanTimestamp(dateTime.getTime());
2392     }
2393 
2394     /**
2395      * Checks if the value is less than the specified <tt>value</tt>.
2396      * <p>
2397      * Only a single {@link #lessThan(int) lessThan(...)} comparison can be
2398      * used. Calling multiple {@link #lessThan(byte[]) lessThan(...)} methods
2399      * overwrites previous values. In addition any {@link #equals(boolean)
2400      * equals(...)} condition is removed since no equality operator is supported
2401      * by MongoDB.
2402      * </p>
2403      * 
2404      * @param value
2405      *            The value to compare the field against.
2406      * @return The condition builder for chaining method calls.
2407      */
2408     public ConditionBuilder lessThan(final double value) {
2409         myEqualsComparison = null;
2410         myOtherComparisons.put(ComparisonOperator.LT, new DoubleElement(
2411                 ComparisonOperator.LT.getToken(), value));
2412         return this;
2413     }
2414 
2415     /**
2416      * Checks if the value is less than the specified <tt>value</tt>.
2417      * <p>
2418      * Only a single {@link #lessThan(int) lessThan(...)} comparison can be
2419      * used. Calling multiple {@link #lessThan(byte[]) lessThan(...)} methods
2420      * overwrites previous values. In addition any {@link #equals(boolean)
2421      * equals(...)} condition is removed since no equality operator is supported
2422      * by MongoDB.
2423      * </p>
2424      * 
2425      * @param value
2426      *            The value to compare the field against.
2427      * @return The condition builder for chaining method calls.
2428      */
2429     public ConditionBuilder lessThan(final int value) {
2430         myEqualsComparison = null;
2431         myOtherComparisons.put(ComparisonOperator.LT, new IntegerElement(
2432                 ComparisonOperator.LT.getToken(), value));
2433         return this;
2434     }
2435 
2436     /**
2437      * Checks if the value is less than the specified <tt>value</tt>.
2438      * <p>
2439      * Only a single {@link #lessThan(int) lessThan(...)} comparison can be
2440      * used. Calling multiple {@link #lessThan(byte[]) lessThan(...)} methods
2441      * overwrites previous values. In addition any {@link #equals(boolean)
2442      * equals(...)} condition is removed since no equality operator is supported
2443      * by MongoDB.
2444      * </p>
2445      * 
2446      * @param value
2447      *            The value to compare the field against.
2448      * @return The condition builder for chaining method calls.
2449      */
2450     public ConditionBuilder lessThan(final long value) {
2451         myEqualsComparison = null;
2452         myOtherComparisons.put(ComparisonOperator.LT, new LongElement(
2453                 ComparisonOperator.LT.getToken(), value));
2454         return this;
2455     }
2456 
2457     /**
2458      * Checks if the value is less than the specified <tt>value</tt>.
2459      * <p>
2460      * Only a single {@link #lessThan(int) lessThan(...)} comparison can be
2461      * used. Calling multiple {@link #lessThan(byte[]) lessThan(...)} methods
2462      * overwrites previous values. In addition any {@link #equals(boolean)
2463      * equals(...)} condition is removed since no equality operator is supported
2464      * by MongoDB.
2465      * </p>
2466      * 
2467      * @param value
2468      *            The value to compare the field against.
2469      * @return The condition builder for chaining method calls.
2470      */
2471     public ConditionBuilder lessThan(final ObjectId value) {
2472         myEqualsComparison = null;
2473         myOtherComparisons.put(ComparisonOperator.LT, new ObjectIdElement(
2474                 ComparisonOperator.LT.getToken(), value));
2475         return this;
2476     }
2477 
2478     /**
2479      * Checks if the value is less than the specified <tt>value</tt>.
2480      * <p>
2481      * Only a single {@link #lessThan(int) lessThan(...)} comparison can be
2482      * used. Calling multiple {@link #lessThan(byte[]) lessThan(...)} methods
2483      * overwrites previous values. In addition any {@link #equals(boolean)
2484      * equals(...)} condition is removed since no equality operator is supported
2485      * by MongoDB.
2486      * </p>
2487      * 
2488      * @param value
2489      *            The value to compare the field against.
2490      * @return The condition builder for chaining method calls.
2491      */
2492     public ConditionBuilder lessThan(final String value) {
2493         myEqualsComparison = null;
2494         myOtherComparisons.put(ComparisonOperator.LT, new StringElement(
2495                 ComparisonOperator.LT.getToken(), value));
2496         return this;
2497     }
2498 
2499     /**
2500      * Checks if the value is less than the specified <tt>value</tt>.
2501      * <p>
2502      * Only a single {@link #lessThan(int) lessThan(...)} comparison can be
2503      * used. Calling multiple {@link #lessThan(byte[]) lessThan(...)} methods
2504      * overwrites previous values. In addition any {@link #equals(boolean)
2505      * equals(...)} condition is removed since no equality operator is supported
2506      * by MongoDB.
2507      * </p>
2508      * 
2509      * @param value
2510      *            The value to compare the field against.
2511      * @return The condition builder for chaining method calls.
2512      */
2513     public ConditionBuilder lessThanMongoTimestamp(final long value) {
2514         myEqualsComparison = null;
2515         myOtherComparisons.put(ComparisonOperator.LT,
2516                 new MongoTimestampElement(ComparisonOperator.LT.getToken(),
2517                         value));
2518         return this;
2519     }
2520 
2521     /**
2522      * Checks if the value is less than or equals the specified <tt>value</tt>.
2523      * <p>
2524      * Only a single {@link #lessThanOrEqualTo(int) lessThanOrEqualTo(...)}
2525      * comparison can be used. Calling multiple
2526      * {@link #lessThanOrEqualTo(byte[]) lessThanOrEqualTo(...)} methods
2527      * overwrites previous values. In addition any {@link #equals(boolean)
2528      * equals(...)} condition is removed since no equality operator is supported
2529      * by MongoDB.
2530      * </p>
2531      * 
2532      * @param subType
2533      *            The binary values subtype.
2534      * @param value
2535      *            The value to compare the field against.
2536      * @return The condition builder for chaining method calls.
2537      */
2538     public ConditionBuilder lessThanOrEqualTo(final byte subType,
2539             final byte[] value) {
2540         myEqualsComparison = null;
2541         myOtherComparisons.put(ComparisonOperator.LTE, new BinaryElement(
2542                 ComparisonOperator.LTE.getToken(), subType, value));
2543         return this;
2544     }
2545 
2546     /**
2547      * Checks if the value is less than or equals the specified <tt>value</tt>.
2548      * <p>
2549      * Only a single {@link #lessThanOrEqualTo(int) lessThanOrEqualTo(...)}
2550      * comparison can be used. Calling multiple
2551      * {@link #lessThanOrEqualTo(byte[]) lessThanOrEqualTo(...)} methods
2552      * overwrites previous values. In addition any {@link #equals(boolean)
2553      * equals(...)} condition is removed since no equality operator is supported
2554      * by MongoDB.
2555      * </p>
2556      * 
2557      * @param value
2558      *            The value to compare the field against.
2559      * @return The condition builder for chaining method calls.
2560      */
2561     public ConditionBuilder lessThanOrEqualTo(final byte[] value) {
2562         myEqualsComparison = null;
2563         myOtherComparisons.put(ComparisonOperator.LTE, new BinaryElement(
2564                 ComparisonOperator.LTE.getToken(), value));
2565         return this;
2566     }
2567 
2568     /**
2569      * Checks if the value is less than or equals the specified
2570      * <tt>dateTime</tt>.
2571      * <p>
2572      * This is equivalent to {@link #lessThanOrEqualToTimestamp(long)
2573      * lessThanOrEqualToTimestamp(dateTime.getTime())}.
2574      * </p>
2575      * <p>
2576      * Only a single {@link #lessThanOrEqualTo(int) lessThanOrEqualTo(...)}
2577      * comparison can be used. Calling multiple
2578      * {@link #lessThanOrEqualTo(byte[]) lessThanOrEqualTo(...)} methods
2579      * overwrites previous values. In addition any {@link #equals(boolean)
2580      * equals(...)} condition is removed since no equality operator is supported
2581      * by MongoDB.
2582      * </p>
2583      * 
2584      * @param dateTime
2585      *            The value to compare the field against.
2586      * @return The condition builder for chaining method calls.
2587      * @see #lessThanOrEqualToTimestamp(long)
2588      */
2589     public ConditionBuilder lessThanOrEqualTo(final Date dateTime) {
2590         return lessThanOrEqualToTimestamp(dateTime.getTime());
2591     }
2592 
2593     /**
2594      * Checks if the value is less than or equals the specified <tt>value</tt>.
2595      * <p>
2596      * Only a single {@link #lessThanOrEqualTo(int) lessThanOrEqualTo(...)}
2597      * comparison can be used. Calling multiple
2598      * {@link #lessThanOrEqualTo(byte[]) lessThanOrEqualTo(...)} methods
2599      * overwrites previous values. In addition any {@link #equals(boolean)
2600      * equals(...)} condition is removed since no equality operator is supported
2601      * by MongoDB.
2602      * </p>
2603      * 
2604      * @param value
2605      *            The value to compare the field against.
2606      * @return The condition builder for chaining method calls.
2607      */
2608     public ConditionBuilder lessThanOrEqualTo(final double value) {
2609         myEqualsComparison = null;
2610         myOtherComparisons.put(ComparisonOperator.LTE, new DoubleElement(
2611                 ComparisonOperator.LTE.getToken(), value));
2612         return this;
2613     }
2614 
2615     /**
2616      * Checks if the value is less than or equals the specified <tt>value</tt>.
2617      * <p>
2618      * Only a single {@link #lessThanOrEqualTo(int) lessThanOrEqualTo(...)}
2619      * comparison can be used. Calling multiple
2620      * {@link #lessThanOrEqualTo(byte[]) lessThanOrEqualTo(...)} methods
2621      * overwrites previous values. In addition any {@link #equals(boolean)
2622      * equals(...)} condition is removed since no equality operator is supported
2623      * by MongoDB.
2624      * </p>
2625      * 
2626      * @param value
2627      *            The value to compare the field against.
2628      * @return The condition builder for chaining method calls.
2629      */
2630     public ConditionBuilder lessThanOrEqualTo(final int value) {
2631         myEqualsComparison = null;
2632         myOtherComparisons.put(ComparisonOperator.LTE, new IntegerElement(
2633                 ComparisonOperator.LTE.getToken(), value));
2634         return this;
2635     }
2636 
2637     /**
2638      * Checks if the value is less than or equals the specified <tt>value</tt>.
2639      * <p>
2640      * Only a single {@link #lessThanOrEqualTo(int) lessThanOrEqualTo(...)}
2641      * comparison can be used. Calling multiple
2642      * {@link #lessThanOrEqualTo(byte[]) lessThanOrEqualTo(...)} methods
2643      * overwrites previous values. In addition any {@link #equals(boolean)
2644      * equals(...)} condition is removed since no equality operator is supported
2645      * by MongoDB.
2646      * </p>
2647      * 
2648      * @param value
2649      *            The value to compare the field against.
2650      * @return The condition builder for chaining method calls.
2651      */
2652     public ConditionBuilder lessThanOrEqualTo(final long value) {
2653         myEqualsComparison = null;
2654         myOtherComparisons.put(ComparisonOperator.LTE, new LongElement(
2655                 ComparisonOperator.LTE.getToken(), value));
2656         return this;
2657     }
2658 
2659     /**
2660      * Checks if the value is less than or equals the specified <tt>value</tt>.
2661      * <p>
2662      * Only a single {@link #lessThanOrEqualTo(int) lessThanOrEqualTo(...)}
2663      * comparison can be used. Calling multiple
2664      * {@link #lessThanOrEqualTo(byte[]) lessThanOrEqualTo(...)} methods
2665      * overwrites previous values. In addition any {@link #equals(boolean)
2666      * equals(...)} condition is removed since no equality operator is supported
2667      * by MongoDB.
2668      * </p>
2669      * 
2670      * @param value
2671      *            The value to compare the field against.
2672      * @return The condition builder for chaining method calls.
2673      */
2674     public ConditionBuilder lessThanOrEqualTo(final ObjectId value) {
2675         myEqualsComparison = null;
2676         myOtherComparisons.put(ComparisonOperator.LTE, new ObjectIdElement(
2677                 ComparisonOperator.LTE.getToken(), value));
2678         return this;
2679     }
2680 
2681     /**
2682      * Checks if the value is less than or equals the specified <tt>value</tt>.
2683      * <p>
2684      * Only a single {@link #lessThanOrEqualTo(int) lessThanOrEqualTo(...)}
2685      * comparison can be used. Calling multiple
2686      * {@link #lessThanOrEqualTo(byte[]) lessThanOrEqualTo(...)} methods
2687      * overwrites previous values. In addition any {@link #equals(boolean)
2688      * equals(...)} condition is removed since no equality operator is supported
2689      * by MongoDB.
2690      * </p>
2691      * 
2692      * @param value
2693      *            The value to compare the field against.
2694      * @return The condition builder for chaining method calls.
2695      */
2696     public ConditionBuilder lessThanOrEqualTo(final String value) {
2697         myEqualsComparison = null;
2698         myOtherComparisons.put(ComparisonOperator.LTE, new StringElement(
2699                 ComparisonOperator.LTE.getToken(), value));
2700         return this;
2701     }
2702 
2703     /**
2704      * Checks if the value is less than or equals the specified <tt>value</tt>.
2705      * <p>
2706      * Only a single {@link #lessThanOrEqualTo(int) lessThanOrEqualTo(...)}
2707      * comparison can be used. Calling multiple
2708      * {@link #lessThanOrEqualTo(byte[]) lessThanOrEqualTo(...)} methods
2709      * overwrites previous values. In addition any {@link #equals(boolean)
2710      * equals(...)} condition is removed since no equality operator is supported
2711      * by MongoDB.
2712      * </p>
2713      * 
2714      * @param value
2715      *            The value to compare the field against.
2716      * @return The condition builder for chaining method calls.
2717      */
2718     public ConditionBuilder lessThanOrEqualToMongoTimestamp(final long value) {
2719         myEqualsComparison = null;
2720         myOtherComparisons.put(ComparisonOperator.LTE,
2721                 new MongoTimestampElement(ComparisonOperator.LTE.getToken(),
2722                         value));
2723         return this;
2724     }
2725 
2726     /**
2727      * Checks if the value is less than or equals the specified <tt>value</tt>.
2728      * <p>
2729      * Only a single {@link #lessThanOrEqualTo(int) lessThanOrEqualTo(...)}
2730      * comparison can be used. Calling multiple
2731      * {@link #lessThanOrEqualTo(byte[]) lessThanOrEqualTo(...)} methods
2732      * overwrites previous values. In addition any {@link #equals(boolean)
2733      * equals(...)} condition is removed since no equality operator is supported
2734      * by MongoDB.
2735      * </p>
2736      * 
2737      * @param value
2738      *            The value to compare the field against.
2739      * @return The condition builder for chaining method calls.
2740      */
2741     public ConditionBuilder lessThanOrEqualToSymbol(final String value) {
2742         myEqualsComparison = null;
2743         myOtherComparisons.put(ComparisonOperator.LTE, new SymbolElement(
2744                 ComparisonOperator.LTE.getToken(), value));
2745         return this;
2746     }
2747 
2748     /**
2749      * Checks if the value is less than or equals the specified <tt>value</tt>.
2750      * <p>
2751      * Only a single {@link #lessThanOrEqualTo(int) lessThanOrEqualTo(...)}
2752      * comparison can be used. Calling multiple
2753      * {@link #lessThanOrEqualTo(byte[]) lessThanOrEqualTo(...)} methods
2754      * overwrites previous values. In addition any {@link #equals(boolean)
2755      * equals(...)} condition is removed since no equality operator is supported
2756      * by MongoDB.
2757      * </p>
2758      * 
2759      * @param value
2760      *            The value to compare the field against.
2761      * @return The condition builder for chaining method calls.
2762      */
2763     public ConditionBuilder lessThanOrEqualToTimestamp(final long value) {
2764         myEqualsComparison = null;
2765         myOtherComparisons.put(ComparisonOperator.LTE, new TimestampElement(
2766                 ComparisonOperator.LTE.getToken(), value));
2767         return this;
2768     }
2769 
2770     /**
2771      * Checks if the value is less than the specified <tt>value</tt>.
2772      * <p>
2773      * Only a single {@link #lessThan(int) lessThan(...)} comparison can be
2774      * used. Calling multiple {@link #lessThan(byte[]) lessThan(...)} methods
2775      * overwrites previous values. In addition any {@link #equals(boolean)
2776      * equals(...)} condition is removed since no equality operator is supported
2777      * by MongoDB.
2778      * </p>
2779      * 
2780      * @param value
2781      *            The value to compare the field against.
2782      * @return The condition builder for chaining method calls.
2783      */
2784     public ConditionBuilder lessThanSymbol(final String value) {
2785         myEqualsComparison = null;
2786         myOtherComparisons.put(ComparisonOperator.LT, new SymbolElement(
2787                 ComparisonOperator.LT.getToken(), value));
2788         return this;
2789     }
2790 
2791     /**
2792      * Checks if the value is less than the specified <tt>value</tt>.
2793      * <p>
2794      * Only a single {@link #lessThan(int) lessThan(...)} comparison can be
2795      * used. Calling multiple {@link #lessThan(byte[]) lessThan(...)} methods
2796      * overwrites previous values. In addition any {@link #equals(boolean)
2797      * equals(...)} condition is removed since no equality operator is supported
2798      * by MongoDB.
2799      * </p>
2800      * 
2801      * @param value
2802      *            The value to compare the field against.
2803      * @return The condition builder for chaining method calls.
2804      */
2805     public ConditionBuilder lessThanTimestamp(final long value) {
2806         myEqualsComparison = null;
2807         myOtherComparisons.put(ComparisonOperator.LT, new TimestampElement(
2808                 ComparisonOperator.LT.getToken(), value));
2809         return this;
2810     }
2811 
2812     /**
2813      * Checks if the value matches the specified <tt>pattern</tt>.
2814      * <p>
2815      * NOTE: This checks if the value <b>is</b> a regular expression <b>or</b>
2816      * if it is a string or symbol that matches the regular expression. It is
2817      * functionally equivalent to {@link #equals(Pattern)}.
2818      * <p>
2819      * Only a single {@link #matches(Pattern)} comparison can be used. Calling
2820      * multiple {@link #matches(Pattern)} methods overwrites previous values. In
2821      * addition any {@link #equals(boolean) equals(...)} condition is removed
2822      * since no equality operator is supported by MongoDB.
2823      * </p>
2824      * <p>
2825      * This method is equivalent to calling {@link #exists(boolean)
2826      * exists(true)}.
2827      * </p>
2828      * 
2829      * @param pattern
2830      *            The pattern to match the value against.
2831      * 
2832      * @return The condition builder for chaining method calls.
2833      */
2834     public ConditionBuilder matches(final Pattern pattern) {
2835         myEqualsComparison = null;
2836         myOtherComparisons.put(
2837                 MiscellaneousOperator.REG_EX,
2838                 new RegularExpressionElement(MiscellaneousOperator.REG_EX
2839                         .getToken(), pattern));
2840         return this;
2841     }
2842 
2843     /**
2844      * Checks if the modulo of the documents value and <tt>divisor</tt> equals
2845      * the <tt>remainder</tt>.
2846      * <p>
2847      * Only a single {@link #mod(int,int)} comparison can be used. Calling
2848      * multiple {@link #mod(long,long)} methods overwrites previous values. In
2849      * addition any {@link #equals(boolean) equals(...)} condition is removed
2850      * since no equality operator is supported by MongoDB.
2851      * </p>
2852      * 
2853      * @param divisor
2854      *            The divisor for the modulo operation.
2855      * @param remainder
2856      *            The desired remainder from the modulo operation.
2857      * 
2858      * @return The condition builder for chaining method calls.
2859      */
2860     public ConditionBuilder mod(final int divisor, final int remainder) {
2861         myEqualsComparison = null;
2862 
2863         final ArrayBuilder builder = BuilderFactory.startArray();
2864         builder.addInteger(divisor);
2865         builder.addInteger(remainder);
2866 
2867         myOtherComparisons.put(MiscellaneousOperator.MOD, new ArrayElement(
2868                 MiscellaneousOperator.MOD.getToken(), builder.build()));
2869         return this;
2870     }
2871 
2872     /**
2873      * Checks if the modulo of the documents value and <tt>divisor</tt> equals
2874      * the <tt>remainder</tt>.
2875      * <p>
2876      * Only a single {@link #mod(int,int)} comparison can be used. Calling
2877      * multiple {@link #mod(long,long)} methods overwrites previous values. In
2878      * addition any {@link #equals(boolean) equals(...)} condition is removed
2879      * since no equality operator is supported by MongoDB.
2880      * </p>
2881      * 
2882      * @param divisor
2883      *            The divisor for the modulo operation.
2884      * @param remainder
2885      *            The desired remainder from the modulo operation.
2886      * 
2887      * @return The condition builder for chaining method calls.
2888      */
2889     public ConditionBuilder mod(final long divisor, final long remainder) {
2890         myEqualsComparison = null;
2891 
2892         final ArrayBuilder builder = BuilderFactory.startArray();
2893         builder.addLong(divisor);
2894         builder.addLong(remainder);
2895 
2896         myOtherComparisons.put(MiscellaneousOperator.MOD, new ArrayElement(
2897                 MiscellaneousOperator.MOD.getToken(), builder.build()));
2898         return this;
2899     }
2900 
2901     /**
2902      * Geospatial query for documents whose field is near the specified
2903      * {@link GeoJson GeoJSON} specified geometry.
2904      * <p>
2905      * This method is designed to be use with a GeoJSON document constructed
2906      * with the {@link GeoJson} class<blockquote>
2907      * 
2908      * <pre>
2909      * <code>
2910      * {@link QueryBuilder#where where}("geo").near({@link GeoJson#lineString GeoJson.lineString}( {@link GeoJson#p GeoJson.p}(1,2),{@link GeoJson#p GeoJson.p}(10,11) ) );
2911      * </code>
2912      * </pre>
2913      * 
2914      * </blockquote>
2915      * </p>
2916      * <p>
2917      * <b>NOTE: </b> The {@code $near} operator is not supported with sharded
2918      * clusters.
2919      * </p>
2920      * <p>
2921      * <b>NOTE: </b> The {@code $near} operator with a GeoJSON document requires
2922      * a {@link Index#geo2dSphere(String) 2dsphere} index.
2923      * </p>
2924      * <p>
2925      * Only a single {@link #near} comparison can be used. Calling multiple
2926      * <tt>near(...)</tt> methods overwrites previous values. In addition any
2927      * {@link #equals(boolean) equals(...)} condition is removed since no
2928      * equality operator is supported by MongoDB.
2929      * </p>
2930      * 
2931      * @param geoJsonDoc
2932      *            The GeoJSON document describing the geometry.
2933      * @return The condition builder for chaining method calls.
2934      */
2935     public ConditionBuilder near(final DocumentAssignable geoJsonDoc) {
2936         myEqualsComparison = null;
2937         myOtherComparisons.put(GeospatialOperator.NEAR, new DocumentElement(
2938                 GeospatialOperator.NEAR.getToken(), new DocumentElement(
2939                         GeospatialOperator.GEOMETRY, geoJsonDoc.asDocument())));
2940         myOtherComparisons.remove(GeospatialOperator.MAX_DISTANCE_MODIFIER);
2941 
2942         return this;
2943     }
2944 
2945     /**
2946      * Geospatial query for documents whose field is near the specified
2947      * {@link GeoJson GeoJSON} specified geometry.
2948      * <p>
2949      * This method is designed to be use with a GeoJSON document constructed
2950      * with the {@link GeoJson} class<blockquote>
2951      * 
2952      * <pre>
2953      * <code>
2954      * {@link QueryBuilder#where where}("geo").near({@link GeoJson#lineString GeoJson.lineString}( {@link GeoJson#p GeoJson.p}(1,2),{@link GeoJson#p GeoJson.p}(10,11) ), 42 );
2955      * </code>
2956      * </pre>
2957      * 
2958      * </blockquote>
2959      * </p>
2960      * <p>
2961      * <b>NOTE: </b> The {@code $near} operator is not supported with sharded
2962      * clusters.
2963      * </p>
2964      * <p>
2965      * <b>NOTE: </b> The {@code $near} operator with a GeoJSON document requires
2966      * a {@link Index#geo2dSphere(String) 2dsphere} index.
2967      * </p>
2968      * <p>
2969      * Only a single {@link #near} comparison can be used. Calling multiple
2970      * <tt>near(...)</tt> methods overwrites previous values. In addition any
2971      * {@link #equals(boolean) equals(...)} condition is removed since no
2972      * equality operator is supported by MongoDB.
2973      * </p>
2974      * 
2975      * @param geoJsonDoc
2976      *            The GeoJSON document describing the geometry.
2977      * @param maxDistance
2978      *            Limits to documents returned to those within the specified
2979      *            maximum distance.
2980      * @return The condition builder for chaining method calls.
2981      */
2982     public ConditionBuilder near(final DocumentAssignable geoJsonDoc,
2983             final double maxDistance) {
2984         myEqualsComparison = null;
2985         myOtherComparisons.put(
2986                 GeospatialOperator.NEAR,
2987                 new DocumentElement(GeospatialOperator.NEAR.getToken(),
2988                         new DocumentElement(GeospatialOperator.GEOMETRY,
2989                                 geoJsonDoc.asDocument()), new DoubleElement(
2990                                 GeospatialOperator.MAX_DISTANCE_MODIFIER
2991                                         .getToken(), maxDistance)));
2992         myOtherComparisons.remove(GeospatialOperator.MAX_DISTANCE_MODIFIER);
2993 
2994         return this;
2995     }
2996 
2997     /**
2998      * Geospatial query for documents whose field is near the specified [
2999      * <tt>x</tt>, <tt>y</tt>] coordinates.
3000      * <p>
3001      * <b>NOTE: </b> The <tt>x</tt> and <tt>y</tt> values must be in the range
3002      * [-180, 180) or the query will throw a {@link QueryFailedException}.
3003      * </p>
3004      * <p>
3005      * <b>NOTE: </b> The {@code $near} operator is not supported with sharded
3006      * clusters.
3007      * </p>
3008      * <p>
3009      * Only a single {@link #near} comparison can be used. Calling multiple
3010      * <tt>near(...)</tt> methods overwrites previous values. In addition any
3011      * {@link #equals(boolean) equals(...)} condition is removed since no
3012      * equality operator is supported by MongoDB.
3013      * </p>
3014      * 
3015      * @param x
3016      *            The X coordinate to find documents near.
3017      * @param y
3018      *            The Y coordinate to find documents near.
3019      * @return The condition builder for chaining method calls.
3020      */
3021     public ConditionBuilder near(final double x, final double y) {
3022         myEqualsComparison = null;
3023         myOtherComparisons.put(GeospatialOperator.NEAR, new ArrayElement(
3024                 GeospatialOperator.NEAR.getToken(), new DoubleElement("0", x),
3025                 new DoubleElement("1", y)));
3026         myOtherComparisons.remove(GeospatialOperator.MAX_DISTANCE_MODIFIER);
3027 
3028         return this;
3029     }
3030 
3031     /**
3032      * Geospatial query for documents whose field is near the specified [
3033      * <tt>x</tt>, <tt>y</tt>] coordinates.
3034      * <p>
3035      * <b>NOTE: </b> The <tt>x</tt> and <tt>y</tt> values must be in the range
3036      * [-180, 180) or the query will throw a {@link QueryFailedException}.
3037      * </p>
3038      * <p>
3039      * <b>NOTE: </b> The {@code $near} operator is not supported with sharded
3040      * clusters.
3041      * </p>
3042      * <p>
3043      * Only a single {@link #near} comparison can be used. Calling multiple
3044      * <tt>near(...)</tt> methods overwrites previous values. In addition any
3045      * {@link #equals(boolean) equals(...)} condition is removed since no
3046      * equality operator is supported by MongoDB.
3047      * </p>
3048      * 
3049      * @param x
3050      *            The X coordinate to find documents near.
3051      * @param y
3052      *            The Y coordinate to find documents near.
3053      * @param maxDistance
3054      *            Limits to documents returned to those within the specified
3055      *            maximum distance.
3056      * @return The condition builder for chaining method calls.
3057      */
3058     public ConditionBuilder near(final double x, final double y,
3059             final double maxDistance) {
3060         myEqualsComparison = null;
3061         myOtherComparisons.put(GeospatialOperator.NEAR, new ArrayElement(
3062                 GeospatialOperator.NEAR.getToken(), new DoubleElement("0", x),
3063                 new DoubleElement("1", y)));
3064         myOtherComparisons.put(
3065                 GeospatialOperator.MAX_DISTANCE_MODIFIER,
3066                 new DoubleElement(GeospatialOperator.MAX_DISTANCE_MODIFIER
3067                         .getToken(), maxDistance));
3068 
3069         return this;
3070     }
3071 
3072     /**
3073      * Geospatial query for documents whose field is near the specified [
3074      * <tt>x</tt>, <tt>y</tt>] coordinates.
3075      * <p>
3076      * <b>NOTE: </b> The <tt>x</tt> and <tt>y</tt> values must be in the range
3077      * [-180, 180) or the query will throw a {@link QueryFailedException}.
3078      * </p>
3079      * <p>
3080      * <b>NOTE: </b> The {@code $near} operator is not supported with sharded
3081      * clusters.
3082      * </p>
3083      * <p>
3084      * Only a single {@link #near} comparison can be used. Calling multiple
3085      * <tt>near(...)</tt> methods overwrites previous values. In addition any
3086      * {@link #equals(boolean) equals(...)} condition is removed since no
3087      * equality operator is supported by MongoDB.
3088      * </p>
3089      * 
3090      * @param x
3091      *            The X coordinate to find documents near.
3092      * @param y
3093      *            The Y coordinate to find documents near.
3094      * @return The condition builder for chaining method calls.
3095      */
3096     public ConditionBuilder near(final int x, final int y) {
3097         myEqualsComparison = null;
3098         myOtherComparisons.put(GeospatialOperator.NEAR, new ArrayElement(
3099                 GeospatialOperator.NEAR.getToken(), new IntegerElement("0", x),
3100                 new IntegerElement("1", y)));
3101         myOtherComparisons.remove(GeospatialOperator.MAX_DISTANCE_MODIFIER);
3102 
3103         return this;
3104     }
3105 
3106     /**
3107      * Geospatial query for documents whose field is near the specified [
3108      * <tt>x</tt>, <tt>y</tt>] coordinates.
3109      * <p>
3110      * <b>NOTE: </b> The <tt>x</tt> and <tt>y</tt> values must be in the range
3111      * [-180, 180) or the query will throw a {@link QueryFailedException}.
3112      * </p>
3113      * <p>
3114      * <b>NOTE: </b> The {@code $near} operator is not supported with sharded
3115      * clusters.
3116      * </p>
3117      * <p>
3118      * Only a single {@link #near} comparison can be used. Calling multiple
3119      * <tt>near(...)</tt> methods overwrites previous values. In addition any
3120      * {@link #equals(boolean) equals(...)} condition is removed since no
3121      * equality operator is supported by MongoDB.
3122      * </p>
3123      * 
3124      * @param x
3125      *            The X coordinate to find documents near.
3126      * @param y
3127      *            The Y coordinate to find documents near.
3128      * @param maxDistance
3129      *            Limits to documents returned to those within the specified
3130      *            maximum distance.
3131      * @return The condition builder for chaining method calls.
3132      */
3133     public ConditionBuilder near(final int x, final int y, final int maxDistance) {
3134         myEqualsComparison = null;
3135         myOtherComparisons.put(GeospatialOperator.NEAR, new ArrayElement(
3136                 GeospatialOperator.NEAR.getToken(), new IntegerElement("0", x),
3137                 new IntegerElement("1", y)));
3138         myOtherComparisons.put(
3139                 GeospatialOperator.MAX_DISTANCE_MODIFIER,
3140                 new IntegerElement(GeospatialOperator.MAX_DISTANCE_MODIFIER
3141                         .getToken(), maxDistance));
3142 
3143         return this;
3144     }
3145 
3146     /**
3147      * Geospatial query for documents whose field is near the specified [
3148      * <tt>x</tt>, <tt>y</tt>] coordinates.
3149      * <p>
3150      * <b>NOTE: </b> The <tt>x</tt> and <tt>y</tt> values must be in the range
3151      * [-180, 180) or the query will throw a {@link QueryFailedException}.
3152      * </p>
3153      * <p>
3154      * <b>NOTE: </b> The {@code $near} operator is not supported with sharded
3155      * clusters.
3156      * </p>
3157      * <p>
3158      * Only a single {@link #near} comparison can be used. Calling multiple
3159      * <tt>near(...)</tt> methods overwrites previous values. In addition any
3160      * {@link #equals(boolean) equals(...)} condition is removed since no
3161      * equality operator is supported by MongoDB.
3162      * </p>
3163      * 
3164      * @param x
3165      *            The X coordinate to find documents near.
3166      * @param y
3167      *            The Y coordinate to find documents near.
3168      * @return The condition builder for chaining method calls.
3169      */
3170     public ConditionBuilder near(final long x, final long y) {
3171         myEqualsComparison = null;
3172         myOtherComparisons.put(GeospatialOperator.NEAR, new ArrayElement(
3173                 GeospatialOperator.NEAR.getToken(), new LongElement("0", x),
3174                 new LongElement("1", y)));
3175         myOtherComparisons.remove(GeospatialOperator.MAX_DISTANCE_MODIFIER);
3176 
3177         return this;
3178     }
3179 
3180     /**
3181      * Geospatial query for documents whose field is near the specified [
3182      * <tt>x</tt>, <tt>y</tt>] coordinates.
3183      * <p>
3184      * <b>NOTE:</b> The <tt>x</tt> and <tt>y</tt> values must be in the range
3185      * [-180, 180) or the query will throw a {@link QueryFailedException}.
3186      * </p>
3187      * <p>
3188      * <b>NOTE: </b> The {@code $near} operator is not supported with sharded
3189      * clusters.
3190      * </p>
3191      * <p>
3192      * Only a single {@link #near} comparison can be used. Calling multiple
3193      * <tt>near(...)</tt> methods overwrites previous values. In addition any
3194      * {@link #equals(boolean) equals(...)} condition is removed since no
3195      * equality operator is supported by MongoDB.
3196      * </p>
3197      * 
3198      * @param x
3199      *            The X coordinate to find documents near.
3200      * @param y
3201      *            The Y coordinate to find documents near.
3202      * @param maxDistance
3203      *            Limits to documents returned to those within the specified
3204      *            maximum distance.
3205      * @return The condition builder for chaining method calls.
3206      */
3207     public ConditionBuilder near(final long x, final long y,
3208             final long maxDistance) {
3209         myEqualsComparison = null;
3210         myOtherComparisons.put(GeospatialOperator.NEAR, new ArrayElement(
3211                 GeospatialOperator.NEAR.getToken(), new LongElement("0", x),
3212                 new LongElement("1", y)));
3213         myOtherComparisons.put(
3214                 GeospatialOperator.MAX_DISTANCE_MODIFIER,
3215                 new LongElement(GeospatialOperator.MAX_DISTANCE_MODIFIER
3216                         .getToken(), maxDistance));
3217 
3218         return this;
3219     }
3220 
3221     /**
3222      * Geospatial query for documents whose field is near the specified
3223      * {@link GeoJson GeoJSON} specified geometry on a sphere.
3224      * <p>
3225      * This method is designed to be use with a GeoJSON document constructed
3226      * with the {@link GeoJson} class<blockquote>
3227      * 
3228      * <pre>
3229      * <code>
3230      * {@link QueryBuilder#where where}("geo").nearSphere({@link GeoJson#lineString GeoJson.lineString}( {@link GeoJson#p GeoJson.p}(1,2),{@link GeoJson#p GeoJson.p}(10,11) ) );
3231      * </code>
3232      * </pre>
3233      * 
3234      * </blockquote>
3235      * </p>
3236      * <p>
3237      * <b>NOTE: </b> The {@code $nearSphere} operator is not supported with
3238      * sharded clusters.
3239      * </p>
3240      * <p>
3241      * <b>NOTE: </b> The {@code $nearSphere} operator with a GeoJSON document
3242      * requires a {@link Index#geo2dSphere(String) 2dsphere} index.
3243      * </p>
3244      * <p>
3245      * Only a single {@link #nearSphere} comparison can be used. Calling
3246      * multiple <tt>near(...)</tt> methods overwrites previous values. In
3247      * addition any {@link #equals(boolean) equals(...)} condition is removed
3248      * since no equality operator is supported by MongoDB.
3249      * </p>
3250      * 
3251      * @param geoJsonDoc
3252      *            The GeoJSON document describing the geometry.
3253      * @return The condition builder for chaining method calls.
3254      */
3255     public ConditionBuilder nearSphere(final DocumentAssignable geoJsonDoc) {
3256         myEqualsComparison = null;
3257         myOtherComparisons.put(GeospatialOperator.NEAR_SPHERE,
3258                 new DocumentElement(GeospatialOperator.NEAR_SPHERE.getToken(),
3259                         new DocumentElement(GeospatialOperator.GEOMETRY,
3260                                 geoJsonDoc.asDocument())));
3261         myOtherComparisons.remove(GeospatialOperator.MAX_DISTANCE_MODIFIER);
3262 
3263         return this;
3264     }
3265 
3266     /**
3267      * Geospatial query for documents whose field is near the specified
3268      * {@link GeoJson GeoJSON} specified geometry on a sphere.
3269      * <p>
3270      * This method is designed to be use with a GeoJSON document constructed
3271      * with the {@link GeoJson} class<blockquote>
3272      * 
3273      * <pre>
3274      * <code>
3275      * {@link QueryBuilder#where where}("geo").nearSphere({@link GeoJson#lineString GeoJson.lineString}( {@link GeoJson#p GeoJson.p}(1,2),{@link GeoJson#p GeoJson.p}(10,11) ), 42 );
3276      * </code>
3277      * </pre>
3278      * 
3279      * </blockquote>
3280      * </p>
3281      * <p>
3282      * <b>NOTE: </b> The {@code $nearSphere} operator is not supported with
3283      * sharded clusters.
3284      * </p>
3285      * <p>
3286      * <b>NOTE: </b> The {@code $nearSphere} operator with a GeoJSON document
3287      * requires a {@link Index#geo2dSphere(String) 2dsphere} index.
3288      * </p>
3289      * <p>
3290      * Only a single {@link #nearSphere} comparison can be used. Calling
3291      * multiple <tt>near(...)</tt> methods overwrites previous values. In
3292      * addition any {@link #equals(boolean) equals(...)} condition is removed
3293      * since no equality operator is supported by MongoDB.
3294      * </p>
3295      * 
3296      * @param geoJsonDoc
3297      *            The GeoJSON document describing the geometry.
3298      * @param maxDistance
3299      *            Limits to documents returned to those within the specified
3300      *            maximum distance.
3301      * @return The condition builder for chaining method calls.
3302      */
3303     public ConditionBuilder nearSphere(final DocumentAssignable geoJsonDoc,
3304             final double maxDistance) {
3305         myEqualsComparison = null;
3306         myOtherComparisons.put(
3307                 GeospatialOperator.NEAR_SPHERE,
3308                 new DocumentElement(GeospatialOperator.NEAR_SPHERE.getToken(),
3309                         new DocumentElement(GeospatialOperator.GEOMETRY,
3310                                 geoJsonDoc.asDocument()), new DoubleElement(
3311                                 GeospatialOperator.MAX_DISTANCE_MODIFIER
3312                                         .getToken(), maxDistance)));
3313         myOtherComparisons.remove(GeospatialOperator.MAX_DISTANCE_MODIFIER);
3314 
3315         return this;
3316     }
3317 
3318     /**
3319      * Geospatial query for documents whose field is near the specified [
3320      * <tt>x</tt>, <tt>y</tt>] coordinates on a sphere.
3321      * <p>
3322      * <b>NOTE:</b> The <tt>x</tt> must be within the range [-180, 180) and the
3323      * <tt>y</tt> values must be in the range (-90, 90) or the query will throw
3324      * a {@link QueryFailedException}.
3325      * </p>
3326      * <p>
3327      * <b>NOTE: </b> The {@code $nearSphere} operator is not supported with
3328      * sharded clusters.
3329      * </p>
3330      * <p>
3331      * Only a single {@link #nearSphere} comparison can be used. Calling
3332      * multiple <tt>nearSphere(...)</tt> methods overwrites previous values. In
3333      * addition any {@link #equals(boolean) equals(...)} condition is removed
3334      * since no equality operator is supported by MongoDB.
3335      * </p>
3336      * 
3337      * @param x
3338      *            The X coordinate to find documents near.
3339      * @param y
3340      *            The Y coordinate to find documents near.
3341      * @return The condition builder for chaining method calls.
3342      */
3343     public ConditionBuilder nearSphere(final double x, final double y) {
3344         myEqualsComparison = null;
3345         myOtherComparisons.put(GeospatialOperator.NEAR_SPHERE,
3346                 new ArrayElement(GeospatialOperator.NEAR_SPHERE.getToken(),
3347                         new DoubleElement("0", x), new DoubleElement("1", y)));
3348         myOtherComparisons.remove(GeospatialOperator.MAX_DISTANCE_MODIFIER);
3349 
3350         return this;
3351     }
3352 
3353     /**
3354      * Geospatial query for documents whose field is near the specified [
3355      * <tt>x</tt>, <tt>y</tt>] coordinates on a sphere.
3356      * <p>
3357      * <b>NOTE:</b> The <tt>x</tt> must be within the range [-180, 180) and the
3358      * <tt>y</tt> values must be in the range (-90, 90) or the query will throw
3359      * a {@link QueryFailedException}.
3360      * </p>
3361      * <p>
3362      * <b>NOTE: </b> The {@code $nearSphere} operator is not supported with
3363      * sharded clusters.
3364      * </p>
3365      * <p>
3366      * Only a single {@link #nearSphere} comparison can be used. Calling
3367      * multiple <tt>nearSphere(...)</tt> methods overwrites previous values. In
3368      * addition any {@link #equals(boolean) equals(...)} condition is removed
3369      * since no equality operator is supported by MongoDB.
3370      * </p>
3371      * 
3372      * @param x
3373      *            The X coordinate to find documents near.
3374      * @param y
3375      *            The Y coordinate to find documents near.
3376      * @param maxDistance
3377      *            Limits to documents returned to those within the specified
3378      *            maximum distance.
3379      * @return The condition builder for chaining method calls.
3380      */
3381     public ConditionBuilder nearSphere(final double x, final double y,
3382             final double maxDistance) {
3383         myEqualsComparison = null;
3384         myOtherComparisons.put(GeospatialOperator.NEAR_SPHERE,
3385                 new ArrayElement(GeospatialOperator.NEAR_SPHERE.getToken(),
3386                         new DoubleElement("0", x), new DoubleElement("1", y)));
3387         myOtherComparisons.put(
3388                 GeospatialOperator.MAX_DISTANCE_MODIFIER,
3389                 new DoubleElement(GeospatialOperator.MAX_DISTANCE_MODIFIER
3390                         .getToken(), maxDistance));
3391 
3392         return this;
3393     }
3394 
3395     /**
3396      * Geospatial query for documents whose field is near the specified [
3397      * <tt>x</tt>, <tt>y</tt>] coordinates on a sphere.
3398      * <p>
3399      * <b>NOTE:</b> The <tt>x</tt> must be within the range [-180, 180) and the
3400      * <tt>y</tt> values must be in the range (-90, 90) or the query will throw
3401      * a {@link QueryFailedException}.
3402      * </p>
3403      * <p>
3404      * <b>NOTE: </b> The {@code $nearSphere} operator is not supported with
3405      * sharded clusters.
3406      * </p>
3407      * <p>
3408      * Only a single {@link #nearSphere} comparison can be used. Calling
3409      * multiple <tt>nearSphere(...)</tt> methods overwrites previous values. In
3410      * addition any {@link #equals(boolean) equals(...)} condition is removed
3411      * since no equality operator is supported by MongoDB.
3412      * </p>
3413      * 
3414      * @param x
3415      *            The X coordinate to find documents near.
3416      * @param y
3417      *            The Y coordinate to find documents near.
3418      * @return The condition builder for chaining method calls.
3419      */
3420     public ConditionBuilder nearSphere(final int x, final int y) {
3421         myEqualsComparison = null;
3422         myOtherComparisons
3423                 .put(GeospatialOperator.NEAR_SPHERE, new ArrayElement(
3424                         GeospatialOperator.NEAR_SPHERE.getToken(),
3425                         new IntegerElement("0", x), new IntegerElement("1", y)));
3426         myOtherComparisons.remove(GeospatialOperator.MAX_DISTANCE_MODIFIER);
3427 
3428         return this;
3429     }
3430 
3431     /**
3432      * Geospatial query for documents whose field is near the specified [
3433      * <tt>x</tt>, <tt>y</tt>] coordinates on a sphere.
3434      * <p>
3435      * <b>NOTE:</b> The <tt>x</tt> must be within the range [-180, 180) and the
3436      * <tt>y</tt> values must be in the range (-90, 90) or the query will throw
3437      * a {@link QueryFailedException}.
3438      * </p>
3439      * <p>
3440      * <b>NOTE: </b> The {@code $nearSphere} operator is not supported with
3441      * sharded clusters.
3442      * </p>
3443      * <p>
3444      * Only a single {@link #nearSphere} comparison can be used. Calling
3445      * multiple <tt>nearSphere(...)</tt> methods overwrites previous values. In
3446      * addition any {@link #equals(boolean) equals(...)} condition is removed
3447      * since no equality operator is supported by MongoDB.
3448      * </p>
3449      * 
3450      * @param x
3451      *            The X coordinate to find documents near.
3452      * @param y
3453      *            The Y coordinate to find documents near.
3454      * @param maxDistance
3455      *            Limits to documents returned to those within the specified
3456      *            maximum distance.
3457      * @return The condition builder for chaining method calls.
3458      */
3459     public ConditionBuilder nearSphere(final int x, final int y,
3460             final int maxDistance) {
3461         myEqualsComparison = null;
3462         myOtherComparisons
3463                 .put(GeospatialOperator.NEAR_SPHERE, new ArrayElement(
3464                         GeospatialOperator.NEAR_SPHERE.getToken(),
3465                         new IntegerElement("0", x), new IntegerElement("1", y)));
3466         myOtherComparisons.put(
3467                 GeospatialOperator.MAX_DISTANCE_MODIFIER,
3468                 new IntegerElement(GeospatialOperator.MAX_DISTANCE_MODIFIER
3469                         .getToken(), maxDistance));
3470 
3471         return this;
3472     }
3473 
3474     /**
3475      * Geospatial query for documents whose field is near the specified [
3476      * <tt>x</tt>, <tt>y</tt>] coordinates on a sphere.
3477      * <p>
3478      * <b>NOTE:</b> The <tt>x</tt> must be within the range [-180, 180) and the
3479      * <tt>y</tt> values must be in the range (-90, 90) or the query will throw
3480      * a {@link QueryFailedException}.
3481      * </p>
3482      * <p>
3483      * <b>NOTE: </b> The {@code $nearSphere} operator is not supported with
3484      * sharded clusters.
3485      * </p>
3486      * <p>
3487      * Only a single {@link #nearSphere} comparison can be used. Calling
3488      * multiple <tt>nearSphere(...)</tt> methods overwrites previous values. In
3489      * addition any {@link #equals(boolean) equals(...)} condition is removed
3490      * since no equality operator is supported by MongoDB.
3491      * </p>
3492      * 
3493      * @param x
3494      *            The X coordinate to find documents near.
3495      * @param y
3496      *            The Y coordinate to find documents near.
3497      * @return The condition builder for chaining method calls.
3498      */
3499     public ConditionBuilder nearSphere(final long x, final long y) {
3500         myEqualsComparison = null;
3501         myOtherComparisons.put(GeospatialOperator.NEAR_SPHERE,
3502                 new ArrayElement(GeospatialOperator.NEAR_SPHERE.getToken(),
3503                         new LongElement("0", x), new LongElement("1", y)));
3504         myOtherComparisons.remove(GeospatialOperator.MAX_DISTANCE_MODIFIER);
3505 
3506         return this;
3507     }
3508 
3509     /**
3510      * Geospatial query for documents whose field is near the specified [
3511      * <tt>x</tt>, <tt>y</tt>] coordinates on a sphere.
3512      * <p>
3513      * <b>NOTE:</b> The <tt>x</tt> must be within the range [-180, 180) and the
3514      * <tt>y</tt> values must be in the range (-90, 90) or the query will throw
3515      * a {@link QueryFailedException}.
3516      * </p>
3517      * <p>
3518      * <b>NOTE: </b> The {@code $nearSphere} operator is not supported with
3519      * sharded clusters.
3520      * </p>
3521      * <p>
3522      * Only a single {@link #nearSphere} comparison can be used. Calling
3523      * multiple <tt>nearSphere(...)</tt> methods overwrites previous values. In
3524      * addition any {@link #equals(boolean) equals(...)} condition is removed
3525      * since no equality operator is supported by MongoDB.
3526      * </p>
3527      * 
3528      * @param x
3529      *            The X coordinate to find documents near.
3530      * @param y
3531      *            The Y coordinate to find documents near.
3532      * @param maxDistance
3533      *            Limits to documents returned to those within the specified
3534      *            maximum distance.
3535      * @return The condition builder for chaining method calls.
3536      */
3537     public ConditionBuilder nearSphere(final long x, final long y,
3538             final long maxDistance) {
3539         myEqualsComparison = null;
3540         myOtherComparisons.put(GeospatialOperator.NEAR_SPHERE,
3541                 new ArrayElement(GeospatialOperator.NEAR_SPHERE.getToken(),
3542                         new LongElement("0", x), new LongElement("1", y)));
3543         myOtherComparisons.put(
3544                 GeospatialOperator.MAX_DISTANCE_MODIFIER,
3545                 new LongElement(GeospatialOperator.MAX_DISTANCE_MODIFIER
3546                         .getToken(), maxDistance));
3547 
3548         return this;
3549     }
3550 
3551     /**
3552      * Checks if the value is not equal to the specified <tt>value</tt>.
3553      * <p>
3554      * Only a single {@link #notEqualTo(boolean) notEqualTo(...)} comparison can
3555      * be used. Calling multiple {@link #notEqualTo(byte[]) equals(...)} methods
3556      * overwrites previous values. In addition any {@link #equals(boolean)
3557      * equals(...)} condition is removed since no equality operator is supported
3558      * by MongoDB.
3559      * </p>
3560      * 
3561      * @param value
3562      *            The value to compare the field against.
3563      * @return The condition builder for chaining method calls.
3564      */
3565     public ConditionBuilder notEqualTo(final boolean value) {
3566         myEqualsComparison = null;
3567         myOtherComparisons.put(ComparisonOperator.NE, new BooleanElement(
3568                 ComparisonOperator.NE.getToken(), value));
3569         return this;
3570     }
3571 
3572     /**
3573      * Checks if the value is not equal to the specified <tt>value</tt>.
3574      * <p>
3575      * Only a single {@link #notEqualTo(boolean) notEqualTo(...)} comparison can
3576      * be used. Calling multiple {@link #notEqualTo(byte[]) equals(...)} methods
3577      * overwrites previous values. In addition any {@link #equals(boolean)
3578      * equals(...)} condition is removed since no equality operator is supported
3579      * by MongoDB.
3580      * </p>
3581      * 
3582      * @param subType
3583      *            The binary values subtype.
3584      * @param value
3585      *            The value to compare the field against.
3586      * @return The condition builder for chaining method calls.
3587      */
3588     public ConditionBuilder notEqualTo(final byte subType, final byte[] value) {
3589         myEqualsComparison = null;
3590         myOtherComparisons.put(ComparisonOperator.NE, new BinaryElement(
3591                 ComparisonOperator.NE.getToken(), subType, value));
3592         return this;
3593     }
3594 
3595     /**
3596      * Checks if the value is not equal to the specified <tt>value</tt>.
3597      * <p>
3598      * Only a single {@link #notEqualTo(boolean) notEqualTo(...)} comparison can
3599      * be used. Calling multiple {@link #notEqualTo(byte[]) equals(...)} methods
3600      * overwrites previous values. In addition any {@link #equals(boolean)
3601      * equals(...)} condition is removed since no equality operator is supported
3602      * by MongoDB.
3603      * </p>
3604      * 
3605      * @param value
3606      *            The value to compare the field against.
3607      * @return The condition builder for chaining method calls.
3608      */
3609     public ConditionBuilder notEqualTo(final byte[] value) {
3610         myEqualsComparison = null;
3611         myOtherComparisons.put(ComparisonOperator.NE, new BinaryElement(
3612                 ComparisonOperator.NE.getToken(), value));
3613         return this;
3614     }
3615 
3616     /**
3617      * Checks if the value is not equal to the specified <tt>dateTime</tt>.
3618      * <p>
3619      * This is equivalent to {@link #notEqualToTimestamp(long)
3620      * notEqualToTimestamp(dateTime.getTime())}.
3621      * </p>
3622      * <p>
3623      * Only a single {@link #notEqualTo(boolean) notEqualTo(...)} comparison can
3624      * be used. Calling multiple {@link #notEqualTo(byte[]) equals(...)} methods
3625      * overwrites previous values. In addition any {@link #equals(boolean)
3626      * equals(...)} condition is removed since no equality operator is supported
3627      * by MongoDB.
3628      * </p>
3629      * 
3630      * @param dateTime
3631      *            The value to compare the field against.
3632      * @return The condition builder for chaining method calls.
3633      * @see #notEqualToTimestamp(long)
3634      */
3635     public ConditionBuilder notEqualTo(final Date dateTime) {
3636         return notEqualToTimestamp(dateTime.getTime());
3637     }
3638 
3639     /**
3640      * Checks if the value is not equal to the specified <tt>value</tt>.
3641      * <p>
3642      * Only a single {@link #notEqualTo(boolean) notEqualTo(...)} comparison can
3643      * be used. Calling multiple {@link #notEqualTo(byte[]) equals(...)} methods
3644      * overwrites previous values. In addition any {@link #equals(boolean)
3645      * equals(...)} condition is removed since no equality operator is supported
3646      * by MongoDB.
3647      * </p>
3648      * 
3649      * @param value
3650      *            The value to compare the field against.
3651      * @return The condition builder for chaining method calls.
3652      */
3653     public ConditionBuilder notEqualTo(final DocumentAssignable value) {
3654         myEqualsComparison = null;
3655         myOtherComparisons.put(ComparisonOperator.NE, new DocumentElement(
3656                 ComparisonOperator.NE.getToken(), value.asDocument()));
3657         return this;
3658     }
3659 
3660     /**
3661      * Checks if the value is not equal to the specified <tt>value</tt>.
3662      * <p>
3663      * Only a single {@link #notEqualTo(boolean) notEqualTo(...)} comparison can
3664      * be used. Calling multiple {@link #notEqualTo(byte[]) equals(...)} methods
3665      * overwrites previous values. In addition any {@link #equals(boolean)
3666      * equals(...)} condition is removed since no equality operator is supported
3667      * by MongoDB.
3668      * </p>
3669      * 
3670      * @param value
3671      *            The value to compare the field against.
3672      * @return The condition builder for chaining method calls.
3673      */
3674     public ConditionBuilder notEqualTo(final double value) {
3675         myEqualsComparison = null;
3676         myOtherComparisons.put(ComparisonOperator.NE, new DoubleElement(
3677                 ComparisonOperator.NE.getToken(), value));
3678         return this;
3679     }
3680 
3681     /**
3682      * Checks if the value is not equal to the specified <tt>value</tt>.
3683      * <p>
3684      * Only a single {@link #notEqualTo(boolean) notEqualTo(...)} comparison can
3685      * be used. Calling multiple {@link #notEqualTo(byte[]) equals(...)} methods
3686      * overwrites previous values. In addition any {@link #equals(boolean)
3687      * equals(...)} condition is removed since no equality operator is supported
3688      * by MongoDB.
3689      * </p>
3690      * 
3691      * @param value
3692      *            The value to compare the field against.
3693      * @return The condition builder for chaining method calls.
3694      */
3695     public ConditionBuilder notEqualTo(final int value) {
3696         myEqualsComparison = null;
3697         myOtherComparisons.put(ComparisonOperator.NE, new IntegerElement(
3698                 ComparisonOperator.NE.getToken(), value));
3699         return this;
3700     }
3701 
3702     /**
3703      * Checks if the value is not equal to the specified <tt>value</tt>.
3704      * <p>
3705      * Only a single {@link #notEqualTo(boolean) notEqualTo(...)} comparison can
3706      * be used. Calling multiple {@link #notEqualTo(byte[]) equals(...)} methods
3707      * overwrites previous values. In addition any {@link #equals(boolean)
3708      * equals(...)} condition is removed since no equality operator is supported
3709      * by MongoDB.
3710      * </p>
3711      * 
3712      * @param value
3713      *            The value to compare the field against.
3714      * @return The condition builder for chaining method calls.
3715      */
3716     public ConditionBuilder notEqualTo(final long value) {
3717         myEqualsComparison = null;
3718         myOtherComparisons.put(ComparisonOperator.NE, new LongElement(
3719                 ComparisonOperator.NE.getToken(), value));
3720         return this;
3721     }
3722 
3723     /**
3724      * Checks if the value is not equal to the specified <tt>value</tt>.
3725      * <p>
3726      * Only a single {@link #notEqualTo(boolean) notEqualTo(...)} comparison can
3727      * be used. Calling multiple {@link #notEqualTo(byte[]) equals(...)} methods
3728      * overwrites previous values. In addition any {@link #equals(boolean)
3729      * equals(...)} condition is removed since no equality operator is supported
3730      * by MongoDB.
3731      * </p>
3732      * 
3733      * @param value
3734      *            The value to compare the field against.
3735      * @return The condition builder for chaining method calls.
3736      */
3737     public ConditionBuilder notEqualTo(final ObjectId value) {
3738         myEqualsComparison = null;
3739         myOtherComparisons.put(ComparisonOperator.NE, new ObjectIdElement(
3740                 ComparisonOperator.NE.getToken(), value));
3741         return this;
3742     }
3743 
3744     /**
3745      * Checks if the value is not equal to the specified <tt>value</tt>.
3746      * <p>
3747      * <b>WARNING:</b> Testing has shown that this query will throw a
3748      * {@link QueryFailedException}.
3749      * </p>
3750      * <p>
3751      * Only a single {@link #notEqualTo(boolean) notEqualTo(...)} comparison can
3752      * be used. Calling multiple {@link #notEqualTo(byte[]) equals(...)} methods
3753      * overwrites previous values. In addition any {@link #equals(boolean)
3754      * equals(...)} condition is removed since no equality operator is supported
3755      * by MongoDB.
3756      * </p>
3757      * 
3758      * @param value
3759      *            The value to compare the field against.
3760      * @return The condition builder for chaining method calls.
3761      * 
3762      * @see #matches(Pattern)
3763      */
3764     public ConditionBuilder notEqualTo(final Pattern value) {
3765         myEqualsComparison = null;
3766         myOtherComparisons.put(ComparisonOperator.NE,
3767                 new RegularExpressionElement(ComparisonOperator.NE.getToken(),
3768                         value));
3769         return this;
3770     }
3771 
3772     /**
3773      * Checks if the value is not equal to the specified <tt>value</tt>.
3774      * <p>
3775      * Only a single {@link #notEqualTo(boolean) notEqualTo(...)} comparison can
3776      * be used. Calling multiple {@link #notEqualTo(byte[]) equals(...)} methods
3777      * overwrites previous values. In addition any {@link #equals(boolean)
3778      * equals(...)} condition is removed since no equality operator is supported
3779      * by MongoDB.
3780      * </p>
3781      * 
3782      * @param value
3783      *            The value to compare the field against.
3784      * @return The condition builder for chaining method calls.
3785      */
3786     public ConditionBuilder notEqualTo(final String value) {
3787         myEqualsComparison = null;
3788         myOtherComparisons.put(ComparisonOperator.NE, new StringElement(
3789                 ComparisonOperator.NE.getToken(), value));
3790         return this;
3791     }
3792 
3793     /**
3794      * Checks if the value is not equal to the specified <tt>uuid</tt> using the
3795      * standard UUID byte ordering.
3796      * <p>
3797      * Only a single {@link #notEqualTo(boolean) notEqualTo(...)} comparison can
3798      * be used. Calling multiple {@link #notEqualTo(byte[]) equals(...)} methods
3799      * overwrites previous values. In addition any {@link #equals(boolean)
3800      * equals(...)} condition is removed since no equality operator is supported
3801      * by MongoDB.
3802      * </p>
3803      * 
3804      * @param uuid
3805      *            The value to compare the field against.
3806      * @return The condition builder for chaining method calls.
3807      */
3808     public ConditionBuilder notEqualTo(final UUID uuid) {
3809         myEqualsComparison = null;
3810         myOtherComparisons.put(ComparisonOperator.NE, new UuidElement(
3811                 ComparisonOperator.NE.getToken(), uuid));
3812         return this;
3813     }
3814 
3815     /**
3816      * Checks if the value is not equal to the specified <tt>value</tt>.
3817      * <p>
3818      * Only a single {@link #notEqualTo(boolean) notEqualTo(...)} comparison can
3819      * be used. Calling multiple {@link #notEqualTo(byte[]) equals(...)} methods
3820      * overwrites previous values. In addition any {@link #equals(boolean)
3821      * equals(...)} condition is removed since no equality operator is supported
3822      * by MongoDB.
3823      * </p>
3824      * 
3825      * @param value
3826      *            The value to compare the field against.
3827      * @return The condition builder for chaining method calls.
3828      */
3829     public ConditionBuilder notEqualToJavaScript(final String value) {
3830         myEqualsComparison = null;
3831         myOtherComparisons.put(ComparisonOperator.NE, new JavaScriptElement(
3832                 ComparisonOperator.NE.getToken(), value));
3833         return this;
3834     }
3835 
3836     /**
3837      * Checks if the value is not equal to the specified <tt>value</tt>.
3838      * <p>
3839      * <b>NOTE:</b> Testing has shown that the <tt>scope</tt> is ignored when
3840      * performing the comparison.
3841      * </p>
3842      * <p>
3843      * Only a single {@link #notEqualTo(boolean) notEqualTo(...)} comparison can
3844      * be used. Calling multiple {@link #notEqualTo(byte[]) equals(...)} methods
3845      * overwrites previous values. In addition any {@link #equals(boolean)
3846      * equals(...)} condition is removed since no equality operator is supported
3847      * by MongoDB.
3848      * </p>
3849      * 
3850      * @param value
3851      *            The value to compare the field against.
3852      * @param scope
3853      *            The stored scope value.
3854      * @return The condition builder for chaining method calls.
3855      */
3856     public ConditionBuilder notEqualToJavaScript(final String value,
3857             final DocumentAssignable scope) {
3858         myEqualsComparison = null;
3859         myOtherComparisons.put(
3860                 ComparisonOperator.NE,
3861                 new JavaScriptWithScopeElement(
3862                         ComparisonOperator.NE.getToken(), value, scope
3863                                 .asDocument()));
3864         return this;
3865     }
3866 
3867     /**
3868      * Checks if the value is not equal to the specified <tt>uuid</tt> using the
3869      * legacy Java UUID byte ordering.
3870      * <p>
3871      * Only a single {@link #notEqualTo(boolean) notEqualTo(...)} comparison can
3872      * be used. Calling multiple {@link #notEqualTo(byte[]) equals(...)} methods
3873      * overwrites previous values. In addition any {@link #equals(boolean)
3874      * equals(...)} condition is removed since no equality operator is supported
3875      * by MongoDB.
3876      * </p>
3877      * 
3878      * @param uuid
3879      *            The value to compare the field against.
3880      * @return The condition builder for chaining method calls.
3881      */
3882     public ConditionBuilder notEqualToLegacy(final UUID uuid) {
3883         myEqualsComparison = null;
3884         myOtherComparisons.put(ComparisonOperator.NE, new UuidElement(
3885                 ComparisonOperator.NE.getToken(),
3886                 UuidElement.LEGACY_UUID_SUBTTYPE, uuid));
3887         return this;
3888     }
3889 
3890     /**
3891      * Checks if the value is not equal to the specified <tt>value</tt>.
3892      * <p>
3893      * <b>WARNING:</b> Testing has shown that this query matches all documents
3894      * even if the value of the field is a {@link ElementType#MIN_KEY}. This was
3895      * fixed in 2.6. See SERVER-11369.
3896      * </p>
3897      * <p>
3898      * Only a single {@link #notEqualTo(boolean) notEqualTo(...)} comparison can
3899      * be used. Calling multiple {@link #notEqualTo(byte[]) equals(...)} methods
3900      * overwrites previous values. In addition any {@link #equals(boolean)
3901      * equals(...)} condition is removed since no equality operator is supported
3902      * by MongoDB.
3903      * </p>
3904      * 
3905      * @return The condition builder for chaining method calls.
3906      * 
3907      * @see <a
3908      *      href="https://jira.mongodb.org/browse/SERVER-11369">SERVER-11369</a>
3909      */
3910     public ConditionBuilder notEqualToMaxKey() {
3911         myEqualsComparison = null;
3912         myOtherComparisons.put(ComparisonOperator.NE, new MaxKeyElement(
3913                 ComparisonOperator.NE.getToken()));
3914         return this;
3915     }
3916 
3917     /**
3918      * Checks if the value is not equal to the specified <tt>value</tt>.
3919      * <p>
3920      * <b>WARNING:</b> Testing has shown that this query matches all documents
3921      * even if the value of the field is a {@link ElementType#MIN_KEY}. This was
3922      * fixed in 2.6. See SERVER-11369.
3923      * </p>
3924      * <p>
3925      * Only a single {@link #notEqualTo(boolean) notEqualTo(...)} comparison can
3926      * be used. Calling multiple {@link #notEqualTo(byte[]) equals(...)} methods
3927      * overwrites previous values. In addition any {@link #equals(boolean)
3928      * equals(...)} condition is removed since no equality operator is supported
3929      * by MongoDB.
3930      * </p>
3931      * 
3932      * @return The condition builder for chaining method calls.
3933      * 
3934      * @see <a
3935      *      href="https://jira.mongodb.org/browse/SERVER-11369">SERVER-11369</a>
3936      */
3937     public ConditionBuilder notEqualToMinKey() {
3938         myEqualsComparison = null;
3939         myOtherComparisons.put(ComparisonOperator.NE, new MinKeyElement(
3940                 ComparisonOperator.NE.getToken()));
3941         return this;
3942     }
3943 
3944     /**
3945      * Checks if the value is not equal to the specified <tt>value</tt>.
3946      * <p>
3947      * Only a single {@link #notEqualTo(boolean) notEqualTo(...)} comparison can
3948      * be used. Calling multiple {@link #notEqualTo(byte[]) equals(...)} methods
3949      * overwrites previous values. In addition any {@link #equals(boolean)
3950      * equals(...)} condition is removed since no equality operator is supported
3951      * by MongoDB.
3952      * </p>
3953      * 
3954      * @param value
3955      *            The value to compare the field against.
3956      * @return The condition builder for chaining method calls.
3957      */
3958     public ConditionBuilder notEqualToMongoTimestamp(final long value) {
3959         myEqualsComparison = null;
3960         myOtherComparisons.put(ComparisonOperator.NE,
3961                 new MongoTimestampElement(ComparisonOperator.NE.getToken(),
3962                         value));
3963         return this;
3964     }
3965 
3966     /**
3967      * Checks if the value is not equal to the specified <tt>value</tt>.
3968      * <p>
3969      * Only a single {@link #notEqualTo(boolean) notEqualTo(...)} comparison can
3970      * be used. Calling multiple {@link #notEqualTo(byte[]) equals(...)} methods
3971      * overwrites previous values. In addition any {@link #equals(boolean)
3972      * equals(...)} condition is removed since no equality operator is supported
3973      * by MongoDB.
3974      * </p>
3975      * 
3976      * @return The condition builder for chaining method calls.
3977      */
3978     public ConditionBuilder notEqualToNull() {
3979         myEqualsComparison = null;
3980         myOtherComparisons.put(ComparisonOperator.NE, new NullElement(
3981                 ComparisonOperator.NE.getToken()));
3982         return this;
3983     }
3984 
3985     /**
3986      * Checks if the value is not equal to the specified <tt>value</tt>.
3987      * <p>
3988      * Only a single {@link #notEqualTo(boolean) notEqualTo(...)} comparison can
3989      * be used. Calling multiple {@link #notEqualTo(byte[]) equals(...)} methods
3990      * overwrites previous values. In addition any {@link #equals(boolean)
3991      * equals(...)} condition is removed since no equality operator is supported
3992      * by MongoDB.
3993      * </p>
3994      * 
3995      * @param value
3996      *            The value to compare the field against.
3997      * @return The condition builder for chaining method calls.
3998      */
3999     public ConditionBuilder notEqualToSymbol(final String value) {
4000         myEqualsComparison = null;
4001         myOtherComparisons.put(ComparisonOperator.NE, new SymbolElement(
4002                 ComparisonOperator.NE.getToken(), value));
4003         return this;
4004     }
4005 
4006     /**
4007      * Checks if the value is not equal to the specified <tt>value</tt>.
4008      * <p>
4009      * Only a single {@link #notEqualTo(boolean) notEqualTo(...)} comparison can
4010      * be used. Calling multiple {@link #notEqualTo(byte[]) equals(...)} methods
4011      * overwrites previous values. In addition any {@link #equals(boolean)
4012      * equals(...)} condition is removed since no equality operator is supported
4013      * by MongoDB.
4014      * </p>
4015      * 
4016      * @param value
4017      *            The value to compare the field against.
4018      * @return The condition builder for chaining method calls.
4019      */
4020     public ConditionBuilder notEqualToTimestamp(final long value) {
4021         myEqualsComparison = null;
4022         myOtherComparisons.put(ComparisonOperator.NE, new TimestampElement(
4023                 ComparisonOperator.NE.getToken(), value));
4024         return this;
4025     }
4026 
4027     /**
4028      * Specify the values that must <em>not</em> match the field's value.
4029      * <p>
4030      * Only a single {@link #notIn(ArrayBuilder)} comparison can be used.
4031      * Calling multiple <tt>notIn(...)</tt> methods overwrites previous values.
4032      * In addition any {@link #equals(boolean) equals(...)} condition is removed
4033      * since no equality operator is supported by MongoDB.
4034      * </p>
4035      * 
4036      * @param elements
4037      *            A builder for the values for the comparison. Any changes to
4038      *            the {@link ArrayBuilder} after this method is called are not
4039      *            reflected in the comparison.
4040      * @return The condition builder for chaining method calls.
4041      */
4042     public ConditionBuilder notIn(final ArrayBuilder elements) {
4043         return notIn(elements.build());
4044     }
4045 
4046     /**
4047      * Specify the values that must <em>not</em> match the field's value.
4048      * <p>
4049      * This method can only be used with values of the same BSON type. If mixed
4050      * types need to be used there are several options:
4051      * <ul>
4052      * <li>Use the {@link Expressions#constant Expressions#constant(...)}
4053      * helpers with the {@link #notIn(Constant...)} method.</li>
4054      * <li>Use the {@link ArrayBuilder} with the {@link #notIn(ArrayBuilder)}
4055      * method.</li>
4056      * <li>Manually construct the {@link Element elements} and use the
4057      * {@link #notIn(Element...)} method.</li>
4058      * </ul>
4059      * </p>
4060      * <p>
4061      * Only a single {@link #notIn(ArrayBuilder)} comparison can be used.
4062      * Calling multiple <tt>notIn(...)</tt> methods overwrites previous values.
4063      * In addition any {@link #equals(boolean) equals(...)} condition is removed
4064      * since no equality operator is supported by MongoDB.
4065      * </p>
4066      * 
4067      * @param values
4068      *            The values for the comparison.
4069      * @return The condition builder for chaining method calls.
4070      */
4071     public ConditionBuilder notIn(final boolean... values) {
4072         final ArrayBuilder arrayBuilder = BuilderFactory.startArray();
4073         for (final boolean value : values) {
4074             arrayBuilder.add(value);
4075         }
4076         return notIn(arrayBuilder);
4077     }
4078 
4079     /**
4080      * Specify the values that must <em>not</em> match the field's value.
4081      * <p>
4082      * This method can only be used with values of the same BSON type. If mixed
4083      * types need to be used there are several options:
4084      * <ul>
4085      * <li>Use the {@link Expressions#constant Expressions#constant(...)}
4086      * helpers with the {@link #notIn(Constant...)} method.</li>
4087      * <li>Use the {@link ArrayBuilder} with the {@link #notIn(ArrayBuilder)}
4088      * method.</li>
4089      * <li>Manually construct the {@link Element elements} and use the
4090      * {@link #notIn(Element...)} method.</li>
4091      * </ul>
4092      * </p>
4093      * <p>
4094      * Only a single {@link #notIn(ArrayBuilder)} comparison can be used.
4095      * Calling multiple <tt>notIn(...)</tt> methods overwrites previous values.
4096      * In addition any {@link #equals(boolean) equals(...)} condition is removed
4097      * since no equality operator is supported by MongoDB.
4098      * </p>
4099      * 
4100      * @param values
4101      *            The values for the comparison.
4102      * @return The condition builder for chaining method calls.
4103      */
4104     public ConditionBuilder notIn(final byte[]... values) {
4105         final ArrayBuilder arrayBuilder = BuilderFactory.startArray();
4106         for (final byte[] value : values) {
4107             arrayBuilder.add(value);
4108         }
4109         return notIn(arrayBuilder);
4110     }
4111 
4112     /**
4113      * Specify the values that must <em>not</em> match the field's value.
4114      * <p>
4115      * This method is designed to be used with the {@link Expressions#constant
4116      * Expressions.constant(...)} helper methods.<blockquote>
4117      * 
4118      * <pre>
4119      * <code>
4120      * import static {@link Expressions#constant com.allanbank.mongodb.builder.expression.Expressions.constant};
4121      * 
4122      * DocumentAssignable query = QueryBuilder.where("f").notIn(constant(1), constant(2), constant(3));
4123      * </code>
4124      * </pre>
4125      * 
4126      * </blockquote>
4127      * </p>
4128      * <p>
4129      * Only a single {@link #notIn(Element[])} comparison can be used. Calling
4130      * multiple <tt>notIn(...)</tt> methods overwrites previous values. In
4131      * addition any {@link #equals(boolean) equals(...)} condition is removed
4132      * since no equality operator is supported by MongoDB.
4133      * </p>
4134      * 
4135      * @param values
4136      *            The values for the comparison.
4137      * @return The condition builder for chaining method calls.
4138      */
4139     public ConditionBuilder notIn(final Constant... values) {
4140         myEqualsComparison = null;
4141 
4142         final List<Element> elements = new ArrayList<Element>(values.length);
4143         for (int i = 0; i < values.length; ++i) {
4144             elements.add(values[i].toElement(ArrayElement.nameFor(i)));
4145         }
4146         myOtherComparisons.put(MiscellaneousOperator.NIN, new ArrayElement(
4147                 MiscellaneousOperator.NIN.getToken(), elements));
4148 
4149         return this;
4150     }
4151 
4152     /**
4153      * Specify the values that must <em>not</em> match the field's value.
4154      * <p>
4155      * This method can only be used with values of the same BSON type. If mixed
4156      * types need to be used there are several options:
4157      * <ul>
4158      * <li>Use the {@link Expressions#constant Expressions#constant(...)}
4159      * helpers with the {@link #notIn(Constant...)} method.</li>
4160      * <li>Use the {@link ArrayBuilder} with the {@link #notIn(ArrayBuilder)}
4161      * method.</li>
4162      * <li>Manually construct the {@link Element elements} and use the
4163      * {@link #notIn(Element...)} method.</li>
4164      * </ul>
4165      * </p>
4166      * <p>
4167      * Only a single {@link #notIn(ArrayBuilder)} comparison can be used.
4168      * Calling multiple <tt>notIn(...)</tt> methods overwrites previous values.
4169      * In addition any {@link #equals(boolean) equals(...)} condition is removed
4170      * since no equality operator is supported by MongoDB.
4171      * </p>
4172      * 
4173      * @param values
4174      *            The values for the comparison.
4175      * @return The condition builder for chaining method calls.
4176      */
4177     public ConditionBuilder notIn(final Date... values) {
4178         final ArrayBuilder arrayBuilder = BuilderFactory.startArray();
4179         for (final Date value : values) {
4180             arrayBuilder.add(value);
4181         }
4182         return notIn(arrayBuilder);
4183     }
4184 
4185     /**
4186      * Specify the values that must <em>not</em> match the field's value.
4187      * <p>
4188      * This method can only be used with values of the same BSON type. If mixed
4189      * types need to be used there are several options:
4190      * <ul>
4191      * <li>Use the {@link Expressions#constant Expressions#constant(...)}
4192      * helpers with the {@link #notIn(Constant...)} method.</li>
4193      * <li>Use the {@link ArrayBuilder} with the {@link #notIn(ArrayBuilder)}
4194      * method.</li>
4195      * <li>Manually construct the {@link Element elements} and use the
4196      * {@link #notIn(Element...)} method.</li>
4197      * </ul>
4198      * </p>
4199      * <p>
4200      * Only a single {@link #notIn(ArrayBuilder)} comparison can be used.
4201      * Calling multiple <tt>notIn(...)</tt> methods overwrites previous values.
4202      * In addition any {@link #equals(boolean) equals(...)} condition is removed
4203      * since no equality operator is supported by MongoDB.
4204      * </p>
4205      * 
4206      * @param values
4207      *            The values for the comparison.
4208      * @return The condition builder for chaining method calls.
4209      */
4210     public ConditionBuilder notIn(final DocumentAssignable... values) {
4211         final ArrayBuilder arrayBuilder = BuilderFactory.startArray();
4212         for (final DocumentAssignable value : values) {
4213             arrayBuilder.add(value);
4214         }
4215         return notIn(arrayBuilder);
4216     }
4217 
4218     /**
4219      * Specify the values that must <em>not</em> match the field's value.
4220      * <p>
4221      * This method can only be used with values of the same BSON type. If mixed
4222      * types need to be used there are several options:
4223      * <ul>
4224      * <li>Use the {@link Expressions#constant Expressions#constant(...)}
4225      * helpers with the {@link #notIn(Constant...)} method.</li>
4226      * <li>Use the {@link ArrayBuilder} with the {@link #notIn(ArrayBuilder)}
4227      * method.</li>
4228      * <li>Manually construct the {@link Element elements} and use the
4229      * {@link #notIn(Element...)} method.</li>
4230      * </ul>
4231      * </p>
4232      * <p>
4233      * Only a single {@link #notIn(ArrayBuilder)} comparison can be used.
4234      * Calling multiple <tt>notIn(...)</tt> methods overwrites previous values.
4235      * In addition any {@link #equals(boolean) equals(...)} condition is removed
4236      * since no equality operator is supported by MongoDB.
4237      * </p>
4238      * 
4239      * @param values
4240      *            The values for the comparison.
4241      * @return The condition builder for chaining method calls.
4242      */
4243     public ConditionBuilder notIn(final Double... values) {
4244         final ArrayBuilder arrayBuilder = BuilderFactory.startArray();
4245         for (final Double value : values) {
4246             arrayBuilder.add(value.doubleValue());
4247         }
4248         return notIn(arrayBuilder);
4249     }
4250 
4251     /**
4252      * Specify the values that must <em>not</em> match the field's value.
4253      * <p>
4254      * Only a single {@link #notIn(Element[])} comparison can be used. Calling
4255      * multiple <tt>notIn(...)</tt> methods overwrites previous values. In
4256      * addition any {@link #equals(boolean) equals(...)} condition is removed
4257      * since no equality operator is supported by MongoDB.
4258      * </p>
4259      * 
4260      * @param elements
4261      *            The element values for the comparison.
4262      * @return The condition builder for chaining method calls.
4263      */
4264     public ConditionBuilder notIn(final Element... elements) {
4265         myEqualsComparison = null;
4266         myOtherComparisons.put(MiscellaneousOperator.NIN, new ArrayElement(
4267                 MiscellaneousOperator.NIN.getToken(), elements));
4268 
4269         return this;
4270     }
4271 
4272     /**
4273      * Specify the values that must <em>not</em> match the field's value.
4274      * <p>
4275      * This method can only be used with values of the same BSON type. If mixed
4276      * types need to be used there are several options:
4277      * <ul>
4278      * <li>Use the {@link Expressions#constant Expressions#constant(...)}
4279      * helpers with the {@link #notIn(Constant...)} method.</li>
4280      * <li>Use the {@link ArrayBuilder} with the {@link #notIn(ArrayBuilder)}
4281      * method.</li>
4282      * <li>Manually construct the {@link Element elements} and use the
4283      * {@link #notIn(Element...)} method.</li>
4284      * </ul>
4285      * </p>
4286      * <p>
4287      * Only a single {@link #notIn(ArrayBuilder)} comparison can be used.
4288      * Calling multiple <tt>notIn(...)</tt> methods overwrites previous values.
4289      * In addition any {@link #equals(boolean) equals(...)} condition is removed
4290      * since no equality operator is supported by MongoDB.
4291      * </p>
4292      * 
4293      * @param values
4294      *            The values for the comparison.
4295      * @return The condition builder for chaining method calls.
4296      */
4297     public ConditionBuilder notIn(final Integer... values) {
4298         final ArrayBuilder arrayBuilder = BuilderFactory.startArray();
4299         for (final Integer value : values) {
4300             arrayBuilder.add(value.intValue());
4301         }
4302         return notIn(arrayBuilder);
4303     }
4304 
4305     /**
4306      * Specify the values that must <em>not</em> match the field's value.
4307      * <p>
4308      * This method can only be used with values of the same BSON type. If mixed
4309      * types need to be used there are several options:
4310      * <ul>
4311      * <li>Use the {@link Expressions#constant Expressions#constant(...)}
4312      * helpers with the {@link #notIn(Constant...)} method.</li>
4313      * <li>Use the {@link ArrayBuilder} with the {@link #notIn(ArrayBuilder)}
4314      * method.</li>
4315      * <li>Manually construct the {@link Element elements} and use the
4316      * {@link #notIn(Element...)} method.</li>
4317      * </ul>
4318      * </p>
4319      * <p>
4320      * Only a single {@link #notIn(ArrayBuilder)} comparison can be used.
4321      * Calling multiple <tt>notIn(...)</tt> methods overwrites previous values.
4322      * In addition any {@link #equals(boolean) equals(...)} condition is removed
4323      * since no equality operator is supported by MongoDB.
4324      * </p>
4325      * 
4326      * @param values
4327      *            The values for the comparison.
4328      * @return The condition builder for chaining method calls.
4329      */
4330     public ConditionBuilder notIn(final Long... values) {
4331         final ArrayBuilder arrayBuilder = BuilderFactory.startArray();
4332         for (final Long value : values) {
4333             arrayBuilder.add(value.longValue());
4334         }
4335         return notIn(arrayBuilder);
4336     }
4337 
4338     /**
4339      * Specify the values that must <em>not</em> match the field's value.
4340      * <p>
4341      * This method can only be used with values of the same BSON type. If mixed
4342      * types need to be used there are several options:
4343      * <ul>
4344      * <li>Use the {@link Expressions#constant Expressions#constant(...)}
4345      * helpers with the {@link #notIn(Constant...)} method.</li>
4346      * <li>Use the {@link ArrayBuilder} with the {@link #notIn(ArrayBuilder)}
4347      * method.</li>
4348      * <li>Manually construct the {@link Element elements} and use the
4349      * {@link #notIn(Element...)} method.</li>
4350      * </ul>
4351      * </p>
4352      * <p>
4353      * Only a single {@link #notIn(ArrayBuilder)} comparison can be used.
4354      * Calling multiple <tt>notIn(...)</tt> methods overwrites previous values.
4355      * In addition any {@link #equals(boolean) equals(...)} condition is removed
4356      * since no equality operator is supported by MongoDB.
4357      * </p>
4358      * 
4359      * @param values
4360      *            The values for the comparison.
4361      * @return The condition builder for chaining method calls.
4362      */
4363     public ConditionBuilder notIn(final ObjectId... values) {
4364         final ArrayBuilder arrayBuilder = BuilderFactory.startArray();
4365         for (final ObjectId value : values) {
4366             arrayBuilder.add(value);
4367         }
4368         return notIn(arrayBuilder);
4369     }
4370 
4371     /**
4372      * Specify the values that must <em>not</em> match the field's value.
4373      * <p>
4374      * This method can only be used with values of the same BSON type. If mixed
4375      * types need to be used there are several options:
4376      * <ul>
4377      * <li>Use the {@link Expressions#constant Expressions#constant(...)}
4378      * helpers with the {@link #notIn(Constant...)} method.</li>
4379      * <li>Use the {@link ArrayBuilder} with the {@link #notIn(ArrayBuilder)}
4380      * method.</li>
4381      * <li>Manually construct the {@link Element elements} and use the
4382      * {@link #notIn(Element...)} method.</li>
4383      * </ul>
4384      * </p>
4385      * <p>
4386      * Only a single {@link #notIn(ArrayBuilder)} comparison can be used.
4387      * Calling multiple <tt>notIn(...)</tt> methods overwrites previous values.
4388      * In addition any {@link #equals(boolean) equals(...)} condition is removed
4389      * since no equality operator is supported by MongoDB.
4390      * </p>
4391      * 
4392      * @param values
4393      *            The values for the comparison.
4394      * @return The condition builder for chaining method calls.
4395      */
4396     public ConditionBuilder notIn(final Pattern... values) {
4397         final ArrayBuilder arrayBuilder = BuilderFactory.startArray();
4398         for (final Pattern value : values) {
4399             arrayBuilder.add(value);
4400         }
4401         return notIn(arrayBuilder);
4402     }
4403 
4404     /**
4405      * Specify the values that must <em>not</em> match the field's value.
4406      * <p>
4407      * This method can only be used with values of the same BSON type. If mixed
4408      * types need to be used there are several options:
4409      * <ul>
4410      * <li>Use the {@link Expressions#constant Expressions#constant(...)}
4411      * helpers with the {@link #notIn(Constant...)} method.</li>
4412      * <li>Use the {@link ArrayBuilder} with the {@link #notIn(ArrayBuilder)}
4413      * method.</li>
4414      * <li>Manually construct the {@link Element elements} and use the
4415      * {@link #notIn(Element...)} method.</li>
4416      * </ul>
4417      * </p>
4418      * <p>
4419      * Only a single {@link #notIn(ArrayBuilder)} comparison can be used.
4420      * Calling multiple <tt>notIn(...)</tt> methods overwrites previous values.
4421      * In addition any {@link #equals(boolean) equals(...)} condition is removed
4422      * since no equality operator is supported by MongoDB.
4423      * </p>
4424      * 
4425      * @param values
4426      *            The values for the comparison.
4427      * @return The condition builder for chaining method calls.
4428      */
4429     public ConditionBuilder notIn(final String... values) {
4430         final ArrayBuilder arrayBuilder = BuilderFactory.startArray();
4431         for (final String value : values) {
4432             arrayBuilder.add(value);
4433         }
4434         return notIn(arrayBuilder);
4435     }
4436 
4437     /**
4438      * Specify the values that must <em>not</em> match the field's value.
4439      * <p>
4440      * This method can only be used with values of the same BSON type. If mixed
4441      * types need to be used there are several options:
4442      * <ul>
4443      * <li>Use the {@link Expressions#constant Expressions#constant(...)}
4444      * helpers with the {@link #notIn(Constant...)} method.</li>
4445      * <li>Use the {@link ArrayBuilder} with the {@link #notIn(ArrayBuilder)}
4446      * method.</li>
4447      * <li>Manually construct the {@link Element elements} and use the
4448      * {@link #notIn(Element...)} method.</li>
4449      * </ul>
4450      * </p>
4451      * <p>
4452      * Only a single {@link #notIn(ArrayBuilder)} comparison can be used.
4453      * Calling multiple <tt>notIn(...)</tt> methods overwrites previous values.
4454      * In addition any {@link #equals(boolean) equals(...)} condition is removed
4455      * since no equality operator is supported by MongoDB.
4456      * </p>
4457      * 
4458      * @param values
4459      *            The values for the comparison.
4460      * @return The condition builder for chaining method calls.
4461      */
4462     public ConditionBuilder notIn(final UUID... values) {
4463         final ArrayBuilder arrayBuilder = BuilderFactory.startArray();
4464         for (final UUID value : values) {
4465             arrayBuilder.add(value);
4466         }
4467         return notIn(arrayBuilder);
4468     }
4469 
4470     /**
4471      * Resets the builder back to an empty, no condition, state.
4472      */
4473     public void reset() {
4474         myOtherComparisons.clear();
4475         myEqualsComparison = null;
4476     }
4477 
4478     /**
4479      * Checks if the value is an array of the specified <tt>length</tt>.
4480      * <p>
4481      * Only a single {@link #size(int) lessThan(...)} comparison can be used.
4482      * Calling multiple <tt>size(int)</tt> methods overwrites previous values.
4483      * In addition any {@link #equals(boolean) equals(...)} condition is removed
4484      * since no equality operator is supported by MongoDB.
4485      * </p>
4486      * 
4487      * @param length
4488      *            The value to compare the field's length against.
4489      * @return The condition builder for chaining method calls.
4490      */
4491     public ConditionBuilder size(final int length) {
4492         myEqualsComparison = null;
4493         myOtherComparisons.put(MiscellaneousOperator.SIZE, new IntegerElement(
4494                 MiscellaneousOperator.SIZE.getToken(), length));
4495         return this;
4496     }
4497 
4498     /**
4499      * Adds a text query to the query.
4500      * <p>
4501      * Note that the {@link MiscellaneousOperator#TEXT $text} operator does not
4502      * apply to a specific field but applies to the document as a whole. For
4503      * this reason only a single {@link #text} condition can be used. Calling
4504      * multiple <tt>text(...)</tt> methods overwrites previous values.
4505      * </p>
4506      * 
4507      * @param textSearchExpression
4508      *            The text search expression.
4509      * @return This builder for call chaining.
4510      * 
4511      * @see <a
4512      *      href="http://docs.mongodb.org/manual/tutorial/search-for-text/">Text
4513      *      Search Expressions</a>
4514      */
4515     public ConditionBuilder text(final String textSearchExpression) {
4516         myParent.text(textSearchExpression);
4517 
4518         return this;
4519     }
4520 
4521     /**
4522      * Adds a text query to the query.
4523      * <p>
4524      * Note that the {@link MiscellaneousOperator#TEXT $text} operator does not
4525      * apply to a specific field but applies to the document as a whole. For
4526      * this reason only a single {@link #text} condition can be used. Calling
4527      * multiple <tt>text(...)</tt> methods overwrites previous values.
4528      * </p>
4529      * 
4530      * @param textSearchExpression
4531      *            The text search expression.
4532      * @param language
4533      *            The language of the text search expression.
4534      * @return This builder for call chaining.
4535      * 
4536      * @see <a
4537      *      href="http://docs.mongodb.org/manual/tutorial/search-for-text/">Text
4538      *      Search Expressions</a>
4539      * @see <a
4540      *      href="http://docs.mongodb.org/manual/reference/command/text/#text-search-languages">Text
4541      *      Search Languages</a>
4542      */
4543     public ConditionBuilder text(final String textSearchExpression,
4544             final String language) {
4545         myParent.text(textSearchExpression, language);
4546 
4547         return this;
4548     }
4549 
4550     /**
4551      * Adds an ad-hoc JavaScript condition to the query.
4552      * <p>
4553      * Note that the {@link MiscellaneousOperator#WHERE $where} operator does
4554      * not apply to a specific field but applies to the document as a whole. For
4555      * this reason only a single {@link #where(String)} condition can be used.
4556      * Calling multiple <tt>where(...)</tt> methods overwrites previous values.
4557      * </p>
4558      * 
4559      * @param javaScript
4560      *            The javaScript condition to add.
4561      * @return This builder for call chaining.
4562      */
4563     public ConditionBuilder where(final String javaScript) {
4564         myParent.whereJavaScript(javaScript);
4565 
4566         return this;
4567     }
4568 
4569     /**
4570      * Geospatial query for documents whose field is within the specified
4571      * bounding polygon.
4572      * <p>
4573      * <b>NOTE: </b> The <tt>x</tt> and <tt>y</tt> values must be in the range
4574      * [-180, 180) or the query will throw a {@link QueryFailedException}.
4575      * </p>
4576      * <p>
4577      * Only a single {@link #within} comparison can be used. Calling multiple
4578      * <tt>within(...)</tt> methods overwrites previous values. In addition any
4579      * {@link #equals(boolean) equals(...)} condition is removed since no
4580      * equality operator is supported by MongoDB.
4581      * </p>
4582      * 
4583      * @param uniqueDocs
4584      *            Controls if documents are returned multiple times for multiple
4585      *            matching conditions.
4586      * @param p1
4587      *            The first point defining the bounds of the polygon.
4588      * @param p2
4589      *            The second point defining the bounds of the polygon.
4590      * @param p3
4591      *            The third point defining the bounds of the polygon.
4592      * @param points
4593      *            The remaining points in the polygon.
4594      * @return The condition builder for chaining method calls.
4595      * @deprecated {@code $uniqueDocs} was removed in MongoDB 2.6. This method
4596      *             will not be removed until two releases after the MongoDB 2.6
4597      *             release (e.g. 2.10 if the releases are 2.8 and 2.10).
4598      */
4599     @Deprecated
4600     public ConditionBuilder within(final boolean uniqueDocs, final Point2D p1,
4601             final Point2D p2, final Point2D p3, final Point2D... points) {
4602         myEqualsComparison = null;
4603 
4604         final DocumentBuilder builder = BuilderFactory.start();
4605         final ArrayBuilder box = builder.pushArray(GeospatialOperator.POLYGON);
4606 
4607         box.pushArray().addDouble(p1.getX()).addDouble(p1.getY());
4608         box.pushArray().addDouble(p2.getX()).addDouble(p2.getY());
4609         box.pushArray().addDouble(p3.getX()).addDouble(p3.getY());
4610         for (final Point2D p : points) {
4611             box.pushArray().addDouble(p.getX()).addDouble(p.getY());
4612         }
4613 
4614         builder.addBoolean(GeospatialOperator.UNIQUE_DOCS_MODIFIER, uniqueDocs);
4615 
4616         myOtherComparisons.put(GeospatialOperator.WITHIN, new DocumentElement(
4617                 GeospatialOperator.WITHIN.getToken(), builder.build()));
4618 
4619         return this;
4620     }
4621 
4622     /**
4623      * Geospatial query for documents whose field is near the specified
4624      * {@link GeoJson GeoJSON} specified geometry.
4625      * <p>
4626      * This method is designed to be use with a GeoJSON document constructed
4627      * with the {@link GeoJson} class<blockquote>
4628      * 
4629      * <pre>
4630      * <code>
4631      * {@link QueryBuilder#where where}("geo").near({@link GeoJson#lineString GeoJson.lineString}( {@link GeoJson#p GeoJson.p}(1,2),{@link GeoJson#p GeoJson.p}(10,11) ) );
4632      * </code>
4633      * </pre>
4634      * 
4635      * </blockquote>
4636      * </p>
4637      * <p>
4638      * <b>NOTE: </b> The {@code $near} operator is not supported with sharded
4639      * clusters.
4640      * </p>
4641      * <p>
4642      * <b>NOTE: </b> The {@code $near} operator with a GeoJSON document requires
4643      * a {@link Index#geo2dSphere(String) 2dsphere} index.
4644      * </p>
4645      * <p>
4646      * Only a single {@link #near} comparison can be used. Calling multiple
4647      * <tt>near(...)</tt> methods overwrites previous values. In addition any
4648      * {@link #equals(boolean) equals(...)} condition is removed since no
4649      * equality operator is supported by MongoDB.
4650      * </p>
4651      * 
4652      * @param geoJsonDoc
4653      *            The GeoJSON document describing the geometry.
4654      * @return The condition builder for chaining method calls.
4655      */
4656 
4657     /**
4658      * Geospatial query for documents whose field is within the specified
4659      * {@link GeoJson GeoJSON} specified geometry.
4660      * <p>
4661      * This method is designed to be use with a GeoJSON document constructed
4662      * with the {@link GeoJson} class<blockquote>
4663      * 
4664      * <pre>
4665      * <code>
4666      * {@link QueryBuilder#where where}("geo").within({@link GeoJson#lineString GeoJson.lineString}( {@link GeoJson#p GeoJson.p}(1,2),{@link GeoJson#p GeoJson.p}(10,11) ) );
4667      * </code>
4668      * </pre>
4669      * 
4670      * </blockquote>
4671      * </p>
4672      * <p>
4673      * <b>NOTE: </b> The {@code $within} operator with a GeoJSON document
4674      * requires a {@link Index#geo2dSphere(String) 2dsphere} index.
4675      * </p>
4676      * <p>
4677      * Only a single {@link #within} comparison can be used. Calling multiple
4678      * <tt>within(...)</tt> methods overwrites previous values. In addition any
4679      * {@link #equals(boolean) equals(...)} condition is removed since no
4680      * equality operator is supported by MongoDB.
4681      * </p>
4682      * 
4683      * @param geoJsonDoc
4684      *            The GeoJSON document describing the geometry.
4685      * @return The condition builder for chaining method calls.
4686      */
4687     public ConditionBuilder within(final DocumentAssignable geoJsonDoc) {
4688         myEqualsComparison = null;
4689 
4690         myOtherComparisons.put(GeospatialOperator.WITHIN, new DocumentElement(
4691                 GeospatialOperator.WITHIN.getToken(), new DocumentElement(
4692                         GeospatialOperator.GEOMETRY, geoJsonDoc.asDocument())));
4693 
4694         return this;
4695     }
4696 
4697     /**
4698      * Geospatial query for documents whose field is within the specified
4699      * {@link GeoJson GeoJSON} specified geometry.
4700      * <p>
4701      * This method is designed to be use with a GeoJSON document constructed
4702      * with the {@link GeoJson} class<blockquote>
4703      * 
4704      * <pre>
4705      * <code>
4706      * {@link QueryBuilder#where where}("geo").within({@link GeoJson#lineString GeoJson.lineString}( {@link GeoJson#p GeoJson.p}(1,2),{@link GeoJson#p GeoJson.p}(10,11) ), true );
4707      * </code>
4708      * </pre>
4709      * 
4710      * </blockquote>
4711      * </p>
4712      * <p>
4713      * <b>NOTE: </b> The {@code $within} operator with a GeoJSON document
4714      * requires a {@link Index#geo2dSphere(String) 2dsphere} index.
4715      * </p>
4716      * <p>
4717      * Only a single {@link #within} comparison can be used. Calling multiple
4718      * <tt>within(...)</tt> methods overwrites previous values. In addition any
4719      * {@link #equals(boolean) equals(...)} condition is removed since no
4720      * equality operator is supported by MongoDB.
4721      * </p>
4722      * 
4723      * @param geoJsonDoc
4724      *            The GeoJSON document describing the geometry.
4725      * @param uniqueDocs
4726      *            Controls if documents are returned multiple times for multiple
4727      *            matching conditions.
4728      * @return The condition builder for chaining method calls.
4729      * @deprecated {@code $uniqueDocs} was removed in MongoDB 2.6. This method
4730      *             will not be removed until two releases after the MongoDB 2.6
4731      *             release (e.g. 2.10 if the releases are 2.8 and 2.10).
4732      */
4733     @Deprecated
4734     public ConditionBuilder within(final DocumentAssignable geoJsonDoc,
4735             final boolean uniqueDocs) {
4736         myEqualsComparison = null;
4737 
4738         myOtherComparisons.put(GeospatialOperator.WITHIN, new DocumentElement(
4739                 GeospatialOperator.WITHIN.getToken(), new DocumentElement(
4740                         GeospatialOperator.GEOMETRY, geoJsonDoc.asDocument()),
4741                 new BooleanElement(GeospatialOperator.UNIQUE_DOCS_MODIFIER,
4742                         uniqueDocs)));
4743 
4744         return this;
4745     }
4746 
4747     /**
4748      * Geospatial query for documents whose field is within the specified
4749      * bounding circular region.
4750      * <p>
4751      * <b>NOTE: </b> The <tt>x</tt> and <tt>y</tt> values must be in the range
4752      * [-180, 180) or the query will throw a {@link QueryFailedException}.
4753      * </p>
4754      * <p>
4755      * Only a single {@link #within} comparison can be used. Calling multiple
4756      * <tt>within(...)</tt> methods overwrites previous values. In addition any
4757      * {@link #equals(boolean) equals(...)} condition is removed since no
4758      * equality operator is supported by MongoDB.
4759      * </p>
4760      * 
4761      * @param x
4762      *            The X coordinate for the center of the circle.
4763      * @param y
4764      *            The Y coordinate for the center of the circle.
4765      * @param radius
4766      *            The radius of the circle.
4767      * @return The condition builder for chaining method calls.
4768      */
4769     public ConditionBuilder within(final double x, final double y,
4770             final double radius) {
4771         myEqualsComparison = null;
4772 
4773         final DocumentBuilder builder = BuilderFactory.start();
4774         final ArrayBuilder box = builder.pushArray(GeospatialOperator.CIRCLE);
4775         box.pushArray().addDouble(x).addDouble(y);
4776         box.addDouble(radius);
4777 
4778         myOtherComparisons.put(GeospatialOperator.WITHIN, new DocumentElement(
4779                 GeospatialOperator.WITHIN.getToken(), builder.build()));
4780 
4781         return this;
4782     }
4783 
4784     /**
4785      * Geospatial query for documents whose field is within the specified
4786      * bounding circular region.
4787      * <p>
4788      * <b>NOTE: </b> The <tt>x</tt> and <tt>y</tt> values must be in the range
4789      * [-180, 180) or the query will throw a {@link QueryFailedException}.
4790      * </p>
4791      * <p>
4792      * Only a single {@link #within} comparison can be used. Calling multiple
4793      * <tt>within(...)</tt> methods overwrites previous values. In addition any
4794      * {@link #equals(boolean) equals(...)} condition is removed since no
4795      * equality operator is supported by MongoDB.
4796      * </p>
4797      * 
4798      * @param x
4799      *            The X coordinate for the center of the circle.
4800      * @param y
4801      *            The Y coordinate for the center of the circle.
4802      * @param radius
4803      *            The radius of the circle.
4804      * @param uniqueDocs
4805      *            Controls if documents are returned multiple times for multiple
4806      *            matching conditions.
4807      * @return The condition builder for chaining method calls.
4808      * @deprecated {@code $uniqueDocs} was removed in MongoDB 2.6. This method
4809      *             will not be removed until two releases after the MongoDB 2.6
4810      *             release (e.g. 2.10 if the releases are 2.8 and 2.10).
4811      */
4812     @Deprecated
4813     public ConditionBuilder within(final double x, final double y,
4814             final double radius, final boolean uniqueDocs) {
4815         myEqualsComparison = null;
4816 
4817         final DocumentBuilder builder = BuilderFactory.start();
4818         final ArrayBuilder box = builder.pushArray(GeospatialOperator.CIRCLE);
4819         box.pushArray().addDouble(x).addDouble(y);
4820         box.addDouble(radius);
4821         builder.addBoolean(GeospatialOperator.UNIQUE_DOCS_MODIFIER, uniqueDocs);
4822 
4823         myOtherComparisons.put(GeospatialOperator.WITHIN, new DocumentElement(
4824                 GeospatialOperator.WITHIN.getToken(), builder.build()));
4825 
4826         return this;
4827     }
4828 
4829     /**
4830      * Geospatial query for documents whose field is within the specified
4831      * bounding rectangular region.
4832      * <p>
4833      * <b>NOTE: </b> The <tt>x</tt> and <tt>y</tt> values must be in the range
4834      * [-180, 180) or the query will throw a {@link QueryFailedException}.
4835      * </p>
4836      * <p>
4837      * Only a single {@link #within} comparison can be used. Calling multiple
4838      * <tt>within(...)</tt> methods overwrites previous values. In addition any
4839      * {@link #equals(boolean) equals(...)} condition is removed since no
4840      * equality operator is supported by MongoDB.
4841      * </p>
4842      * 
4843      * @param x1
4844      *            The first X coordinate.
4845      * @param y1
4846      *            The first Y coordinate.
4847      * @param x2
4848      *            The second X coordinate. NOT THE WIDTH.
4849      * @param y2
4850      *            The second Y coordinate. NOT THE HEIGHT.
4851      * @return The condition builder for chaining method calls.
4852      */
4853     public ConditionBuilder within(final double x1, final double y1,
4854             final double x2, final double y2) {
4855         myEqualsComparison = null;
4856 
4857         final DocumentBuilder builder = BuilderFactory.start();
4858         final ArrayBuilder box = builder.pushArray(GeospatialOperator.BOX);
4859         box.pushArray().addDouble(Math.min(x1, x2)).addDouble(Math.min(y1, y2));
4860         box.pushArray().addDouble(Math.max(x1, x2)).addDouble(Math.max(y1, y2));
4861 
4862         myOtherComparisons.put(GeospatialOperator.WITHIN, new DocumentElement(
4863                 GeospatialOperator.WITHIN.getToken(), builder.build()));
4864 
4865         return this;
4866     }
4867 
4868     /**
4869      * Geospatial query for documents whose field is within the specified
4870      * bounding rectangular region.
4871      * <p>
4872      * <b>NOTE: </b> The <tt>x</tt> and <tt>y</tt> values must be in the range
4873      * [-180, 180) or the query will throw a {@link QueryFailedException}.
4874      * </p>
4875      * <p>
4876      * Only a single {@link #within} comparison can be used. Calling multiple
4877      * <tt>within(...)</tt> methods overwrites previous values. In addition any
4878      * {@link #equals(boolean) equals(...)} condition is removed since no
4879      * equality operator is supported by MongoDB.
4880      * </p>
4881      * 
4882      * @param x1
4883      *            The first X coordinate.
4884      * @param y1
4885      *            The first Y coordinate.
4886      * @param x2
4887      *            The second X coordinate. NOT THE WIDTH.
4888      * @param y2
4889      *            The second Y coordinate. NOT THE HEIGHT.
4890      * @param uniqueDocs
4891      *            Controls if documents are returned multiple times for multiple
4892      *            matching conditions.
4893      * @return The condition builder for chaining method calls.
4894      * @deprecated {@code $uniqueDocs} was removed in MongoDB 2.6. This method
4895      *             will not be removed until two releases after the MongoDB 2.6
4896      *             release (e.g. 2.10 if the releases are 2.8 and 2.10).
4897      */
4898     @Deprecated
4899     public ConditionBuilder within(final double x1, final double y1,
4900             final double x2, final double y2, final boolean uniqueDocs) {
4901         myEqualsComparison = null;
4902 
4903         final DocumentBuilder builder = BuilderFactory.start();
4904         final ArrayBuilder box = builder.pushArray(GeospatialOperator.BOX);
4905         box.pushArray().addDouble(Math.min(x1, x2)).addDouble(Math.min(y1, y2));
4906         box.pushArray().addDouble(Math.max(x1, x2)).addDouble(Math.max(y1, y2));
4907         builder.addBoolean(GeospatialOperator.UNIQUE_DOCS_MODIFIER, uniqueDocs);
4908 
4909         myOtherComparisons.put(GeospatialOperator.WITHIN, new DocumentElement(
4910                 GeospatialOperator.WITHIN.getToken(), builder.build()));
4911 
4912         return this;
4913     }
4914 
4915     /**
4916      * Geospatial query for documents whose field is within the specified
4917      * bounding circular region.
4918      * <p>
4919      * <b>NOTE: </b> The <tt>x</tt> and <tt>y</tt> values must be in the range
4920      * [-180, 180) or the query will throw a {@link QueryFailedException}.
4921      * </p>
4922      * <p>
4923      * Only a single {@link #within} comparison can be used. Calling multiple
4924      * <tt>within(...)</tt> methods overwrites previous values. In addition any
4925      * {@link #equals(boolean) equals(...)} condition is removed since no
4926      * equality operator is supported by MongoDB.
4927      * </p>
4928      * 
4929      * @param x
4930      *            The X coordinate for the center of the circle.
4931      * @param y
4932      *            The Y coordinate for the center of the circle.
4933      * @param radius
4934      *            The radius of the circle.
4935      * @return The condition builder for chaining method calls.
4936      */
4937     public ConditionBuilder within(final int x, final int y, final int radius) {
4938         myEqualsComparison = null;
4939 
4940         final DocumentBuilder builder = BuilderFactory.start();
4941         final ArrayBuilder box = builder.pushArray(GeospatialOperator.CIRCLE);
4942         box.pushArray().addInteger(x).addInteger(y);
4943         box.addInteger(radius);
4944 
4945         myOtherComparisons.put(GeospatialOperator.WITHIN, new DocumentElement(
4946                 GeospatialOperator.WITHIN.getToken(), builder.build()));
4947 
4948         return this;
4949     }
4950 
4951     /**
4952      * Geospatial query for documents whose field is within the specified
4953      * bounding circular region.
4954      * <p>
4955      * <b>NOTE: </b> The <tt>x</tt> and <tt>y</tt> values must be in the range
4956      * [-180, 180) or the query will throw a {@link QueryFailedException}.
4957      * </p>
4958      * <p>
4959      * Only a single {@link #within} comparison can be used. Calling multiple
4960      * <tt>within(...)</tt> methods overwrites previous values. In addition any
4961      * {@link #equals(boolean) equals(...)} condition is removed since no
4962      * equality operator is supported by MongoDB.
4963      * </p>
4964      * 
4965      * @param x
4966      *            The X coordinate for the center of the circle.
4967      * @param y
4968      *            The Y coordinate for the center of the circle.
4969      * @param radius
4970      *            The radius of the circle.
4971      * @param uniqueDocs
4972      *            Controls if documents are returned multiple times for multiple
4973      *            matching conditions.
4974      * @return The condition builder for chaining method calls.
4975      * @deprecated {@code $uniqueDocs} was removed in MongoDB 2.6. This method
4976      *             will not be removed until two releases after the MongoDB 2.6
4977      *             release (e.g. 2.10 if the releases are 2.8 and 2.10).
4978      */
4979     @Deprecated
4980     public ConditionBuilder within(final int x, final int y, final int radius,
4981             final boolean uniqueDocs) {
4982         myEqualsComparison = null;
4983 
4984         final DocumentBuilder builder = BuilderFactory.start();
4985         final ArrayBuilder box = builder.pushArray(GeospatialOperator.CIRCLE);
4986         box.pushArray().addInteger(x).addInteger(y);
4987         box.addInteger(radius);
4988         builder.addBoolean(GeospatialOperator.UNIQUE_DOCS_MODIFIER, uniqueDocs);
4989 
4990         myOtherComparisons.put(GeospatialOperator.WITHIN, new DocumentElement(
4991                 GeospatialOperator.WITHIN.getToken(), builder.build()));
4992 
4993         return this;
4994     }
4995 
4996     /**
4997      * Geospatial query for documents whose field is within the specified
4998      * bounding rectangular region.
4999      * <p>
5000      * <b>NOTE: </b> The <tt>x</tt> and <tt>y</tt> values must be in the range
5001      * [-180, 180) or the query will throw a {@link QueryFailedException}.
5002      * </p>
5003      * <p>
5004      * Only a single {@link #within} comparison can be used. Calling multiple
5005      * <tt>within(...)</tt> methods overwrites previous values. In addition any
5006      * {@link #equals(boolean) equals(...)} condition is removed since no
5007      * equality operator is supported by MongoDB.
5008      * </p>
5009      * 
5010      * @param x1
5011      *            The first X coordinate.
5012      * @param y1
5013      *            The first Y coordinate.
5014      * @param x2
5015      *            The second X coordinate. NOT THE WIDTH.
5016      * @param y2
5017      *            The second Y coordinate. NOT THE HEIGHT.
5018      * @return The condition builder for chaining method calls.
5019      */
5020     public ConditionBuilder within(final int x1, final int y1, final int x2,
5021             final int y2) {
5022         myEqualsComparison = null;
5023 
5024         final DocumentBuilder builder = BuilderFactory.start();
5025         final ArrayBuilder box = builder.pushArray(GeospatialOperator.BOX);
5026         box.pushArray().addInteger(Math.min(x1, x2))
5027                 .addInteger(Math.min(y1, y2));
5028         box.pushArray().addInteger(Math.max(x1, x2))
5029                 .addInteger(Math.max(y1, y2));
5030 
5031         myOtherComparisons.put(GeospatialOperator.WITHIN, new DocumentElement(
5032                 GeospatialOperator.WITHIN.getToken(), builder.build()));
5033 
5034         return this;
5035     }
5036 
5037     /**
5038      * Geospatial query for documents whose field is within the specified
5039      * bounding rectangular region.
5040      * <p>
5041      * <b>NOTE: </b> The <tt>x</tt> and <tt>y</tt> values must be in the range
5042      * [-180, 180) or the query will throw a {@link QueryFailedException}.
5043      * </p>
5044      * <p>
5045      * Only a single {@link #within} comparison can be used. Calling multiple
5046      * <tt>within(...)</tt> methods overwrites previous values. In addition any
5047      * {@link #equals(boolean) equals(...)} condition is removed since no
5048      * equality operator is supported by MongoDB.
5049      * </p>
5050      * 
5051      * @param x1
5052      *            The first X coordinate.
5053      * @param y1
5054      *            The first Y coordinate.
5055      * @param x2
5056      *            The second X coordinate. NOT THE WIDTH.
5057      * @param y2
5058      *            The second Y coordinate. NOT THE HEIGHT.
5059      * @param uniqueDocs
5060      *            Controls if documents are returned multiple times for multiple
5061      *            matching conditions.
5062      * @return The condition builder for chaining method calls.
5063      * @deprecated {@code $uniqueDocs} was removed in MongoDB 2.6. This method
5064      *             will not be removed until two releases after the MongoDB 2.6
5065      *             release (e.g. 2.10 if the releases are 2.8 and 2.10).
5066      */
5067     @Deprecated
5068     public ConditionBuilder within(final int x1, final int y1, final int x2,
5069             final int y2, final boolean uniqueDocs) {
5070         myEqualsComparison = null;
5071 
5072         final DocumentBuilder builder = BuilderFactory.start();
5073         final ArrayBuilder box = builder.pushArray(GeospatialOperator.BOX);
5074         box.pushArray().addInteger(Math.min(x1, x2))
5075                 .addInteger(Math.min(y1, y2));
5076         box.pushArray().addInteger(Math.max(x1, x2))
5077                 .addInteger(Math.max(y1, y2));
5078         builder.addBoolean(GeospatialOperator.UNIQUE_DOCS_MODIFIER, uniqueDocs);
5079 
5080         myOtherComparisons.put(GeospatialOperator.WITHIN, new DocumentElement(
5081                 GeospatialOperator.WITHIN.getToken(), builder.build()));
5082 
5083         return this;
5084     }
5085 
5086     /**
5087      * Geospatial query for documents whose field is within the specified
5088      * bounding circular region.
5089      * <p>
5090      * <b>NOTE: </b> The <tt>x</tt> and <tt>y</tt> values must be in the range
5091      * [-180, 180) or the query will throw a {@link QueryFailedException}.
5092      * </p>
5093      * <p>
5094      * Only a single {@link #within} comparison can be used. Calling multiple
5095      * <tt>within(...)</tt> methods overwrites previous values. In addition any
5096      * {@link #equals(boolean) equals(...)} condition is removed since no
5097      * equality operator is supported by MongoDB.
5098      * </p>
5099      * 
5100      * @param x
5101      *            The X coordinate for the center of the circle.
5102      * @param y
5103      *            The Y coordinate for the center of the circle.
5104      * @param radius
5105      *            The radius of the circle.
5106      * @return The condition builder for chaining method calls.
5107      */
5108     public ConditionBuilder within(final long x, final long y, final long radius) {
5109         myEqualsComparison = null;
5110 
5111         final DocumentBuilder builder = BuilderFactory.start();
5112         final ArrayBuilder box = builder.pushArray(GeospatialOperator.CIRCLE);
5113         box.pushArray().addLong(x).addLong(y);
5114         box.addLong(radius);
5115 
5116         myOtherComparisons.put(GeospatialOperator.WITHIN, new DocumentElement(
5117                 GeospatialOperator.WITHIN.getToken(), builder.build()));
5118 
5119         return this;
5120     }
5121 
5122     /**
5123      * Geospatial query for documents whose field is within the specified
5124      * bounding circular region.
5125      * <p>
5126      * <b>NOTE: </b> The <tt>x</tt> and <tt>y</tt> values must be in the range
5127      * [-180, 180) or the query will throw a {@link QueryFailedException}.
5128      * </p>
5129      * <p>
5130      * Only a single {@link #within} comparison can be used. Calling multiple
5131      * <tt>within(...)</tt> methods overwrites previous values. In addition any
5132      * {@link #equals(boolean) equals(...)} condition is removed since no
5133      * equality operator is supported by MongoDB.
5134      * </p>
5135      * 
5136      * @param x
5137      *            The X coordinate for the center of the circle.
5138      * @param y
5139      *            The Y coordinate for the center of the circle.
5140      * @param radius
5141      *            The radius of the circle.
5142      * @param uniqueDocs
5143      *            Controls if documents are returned multiple times for multiple
5144      *            matching conditions.
5145      * @return The condition builder for chaining method calls.
5146      * @deprecated {@code $uniqueDocs} was removed in MongoDB 2.6. This method
5147      *             will not be removed until two releases after the MongoDB 2.6
5148      *             release (e.g. 2.10 if the releases are 2.8 and 2.10).
5149      */
5150     @Deprecated
5151     public ConditionBuilder within(final long x, final long y,
5152             final long radius, final boolean uniqueDocs) {
5153         myEqualsComparison = null;
5154 
5155         final DocumentBuilder builder = BuilderFactory.start();
5156         final ArrayBuilder box = builder.pushArray(GeospatialOperator.CIRCLE);
5157         box.pushArray().addLong(x).addLong(y);
5158         box.addLong(radius);
5159         builder.addBoolean(GeospatialOperator.UNIQUE_DOCS_MODIFIER, uniqueDocs);
5160 
5161         myOtherComparisons.put(GeospatialOperator.WITHIN, new DocumentElement(
5162                 GeospatialOperator.WITHIN.getToken(), builder.build()));
5163 
5164         return this;
5165     }
5166 
5167     /**
5168      * Geospatial query for documents whose field is within the specified
5169      * bounding rectangular region.
5170      * <p>
5171      * <b>NOTE: </b> The <tt>x</tt> and <tt>y</tt> values must be in the range
5172      * [-180, 180) or the query will throw a {@link QueryFailedException}.
5173      * </p>
5174      * <p>
5175      * Only a single {@link #within} comparison can be used. Calling multiple
5176      * <tt>within(...)</tt> methods overwrites previous values. In addition any
5177      * {@link #equals(boolean) equals(...)} condition is removed since no
5178      * equality operator is supported by MongoDB.
5179      * </p>
5180      * 
5181      * @param x1
5182      *            The first X coordinate.
5183      * @param y1
5184      *            The first Y coordinate.
5185      * @param x2
5186      *            The second X coordinate. NOT THE WIDTH.
5187      * @param y2
5188      *            The second Y coordinate. NOT THE HEIGHT.
5189      * @return The condition builder for chaining method calls.
5190      */
5191     public ConditionBuilder within(final long x1, final long y1, final long x2,
5192             final long y2) {
5193         myEqualsComparison = null;
5194 
5195         final DocumentBuilder builder = BuilderFactory.start();
5196         final ArrayBuilder box = builder.pushArray(GeospatialOperator.BOX);
5197         box.pushArray().addLong(Math.min(x1, x2)).addLong(Math.min(y1, y2));
5198         box.pushArray().addLong(Math.max(x1, x2)).addLong(Math.max(y1, y2));
5199 
5200         myOtherComparisons.put(GeospatialOperator.WITHIN, new DocumentElement(
5201                 GeospatialOperator.WITHIN.getToken(), builder.build()));
5202 
5203         return this;
5204     }
5205 
5206     /**
5207      * Geospatial query for documents whose field is within the specified
5208      * bounding rectangular region.
5209      * <p>
5210      * <b>NOTE: </b> The <tt>x</tt> and <tt>y</tt> values must be in the range
5211      * [-180, 180) or the query will throw a {@link QueryFailedException}.
5212      * </p>
5213      * <p>
5214      * Only a single {@link #within} comparison can be used. Calling multiple
5215      * <tt>within(...)</tt> methods overwrites previous values. In addition any
5216      * {@link #equals(boolean) equals(...)} condition is removed since no
5217      * equality operator is supported by MongoDB.
5218      * </p>
5219      * 
5220      * @param x1
5221      *            The first X coordinate.
5222      * @param y1
5223      *            The first Y coordinate.
5224      * @param x2
5225      *            The second X coordinate. NOT THE WIDTH.
5226      * @param y2
5227      *            The second Y coordinate. NOT THE HEIGHT.
5228      * @param uniqueDocs
5229      *            Controls if documents are returned multiple times for multiple
5230      *            matching conditions.
5231      * @return The condition builder for chaining method calls.
5232      * @deprecated {@code $uniqueDocs} was removed in MongoDB 2.6. This method
5233      *             will not be removed until two releases after the MongoDB 2.6
5234      *             release (e.g. 2.10 if the releases are 2.8 and 2.10).
5235      */
5236     @Deprecated
5237     public ConditionBuilder within(final long x1, final long y1, final long x2,
5238             final long y2, final boolean uniqueDocs) {
5239         myEqualsComparison = null;
5240 
5241         final DocumentBuilder builder = BuilderFactory.start();
5242         final ArrayBuilder box = builder.pushArray(GeospatialOperator.BOX);
5243         box.pushArray().addLong(Math.min(x1, x2)).addLong(Math.min(y1, y2));
5244         box.pushArray().addLong(Math.max(x1, x2)).addLong(Math.max(y1, y2));
5245         builder.addBoolean(GeospatialOperator.UNIQUE_DOCS_MODIFIER, uniqueDocs);
5246 
5247         myOtherComparisons.put(GeospatialOperator.WITHIN, new DocumentElement(
5248                 GeospatialOperator.WITHIN.getToken(), builder.build()));
5249 
5250         return this;
5251     }
5252 
5253     /**
5254      * Geospatial query for documents whose field is within the specified
5255      * bounding polygon.
5256      * <p>
5257      * <b>NOTE: </b> The <tt>x</tt> and <tt>y</tt> values must be in the range
5258      * [-180, 180) or the query will throw a {@link QueryFailedException}.
5259      * </p>
5260      * <p>
5261      * Only a single {@link #within} comparison can be used. Calling multiple
5262      * <tt>within(...)</tt> methods overwrites previous values. In addition any
5263      * {@link #equals(boolean) equals(...)} condition is removed since no
5264      * equality operator is supported by MongoDB.
5265      * </p>
5266      * 
5267      * @param p1
5268      *            The first point defining the bounds of the polygon.
5269      * @param p2
5270      *            The second point defining the bounds of the polygon.
5271      * @param p3
5272      *            The third point defining the bounds of the polygon.
5273      * @param points
5274      *            The remaining points in the polygon.
5275      * @return The condition builder for chaining method calls.
5276      */
5277     public ConditionBuilder within(final Point2D p1, final Point2D p2,
5278             final Point2D p3, final Point2D... points) {
5279         myEqualsComparison = null;
5280 
5281         final DocumentBuilder builder = BuilderFactory.start();
5282         final ArrayBuilder polygon = builder
5283                 .pushArray(GeospatialOperator.POLYGON);
5284 
5285         polygon.pushArray().add(p1.getX()).add(p1.getY());
5286         polygon.pushArray().add(p2.getX()).add(p2.getY());
5287         polygon.pushArray().add(p3.getX()).add(p3.getY());
5288         for (final Point2D p : points) {
5289             polygon.pushArray().add(p.getX()).add(p.getY());
5290         }
5291 
5292         myOtherComparisons.put(GeospatialOperator.WITHIN, new DocumentElement(
5293                 GeospatialOperator.WITHIN.getToken(), builder.build()));
5294 
5295         return this;
5296     }
5297 
5298     /**
5299      * Geospatial query for documents whose field is within the specified
5300      * bounding circular region on a sphere.
5301      * <p>
5302      * <b>NOTE:</b> The <tt>x</tt> must be within the range [-180, 180) and the
5303      * <tt>y</tt> values must be in the range (-90, 90) or the query will throw
5304      * a {@link QueryFailedException}.
5305      * </p>
5306      * <p>
5307      * <b>NOTE 2:</b> The <tt>x</tt>, <tt>y</tt> and <tt>radius</tt> must not
5308      * wrap since that has not been implemented yet within MongoDB.
5309      * </p>
5310      * <p>
5311      * Only a single {@link #within} comparison can be used. Calling multiple
5312      * <tt>withinXXX(...)</tt> methods overwrites previous values. In addition
5313      * any {@link #equals(boolean) equals(...)} condition is removed since no
5314      * equality operator is supported by MongoDB.
5315      * </p>
5316      * 
5317      * @param x
5318      *            The X coordinate for the center of the circle.
5319      * @param y
5320      *            The Y coordinate for the center of the circle.
5321      * @param radius
5322      *            The radius of the circle.
5323      * @return The condition builder for chaining method calls.
5324      */
5325     public ConditionBuilder withinOnSphere(final double x, final double y,
5326             final double radius) {
5327         myEqualsComparison = null;
5328 
5329         final DocumentBuilder builder = BuilderFactory.start();
5330         final ArrayBuilder box = builder
5331                 .pushArray(GeospatialOperator.SPHERICAL_CIRCLE);
5332         box.pushArray().addDouble(x).addDouble(y);
5333         box.addDouble(radius);
5334 
5335         myOtherComparisons.put(GeospatialOperator.WITHIN, new DocumentElement(
5336                 GeospatialOperator.WITHIN.getToken(), builder.build()));
5337 
5338         return this;
5339     }
5340 
5341     /**
5342      * Geospatial query for documents whose field is within the specified
5343      * bounding circular region on a sphere.
5344      * <p>
5345      * <b>NOTE:</b> The <tt>x</tt> must be within the range [-180, 180) and the
5346      * <tt>y</tt> values must be in the range (-90, 90) or the query will throw
5347      * a {@link QueryFailedException}.
5348      * </p>
5349      * <p>
5350      * <b>NOTE 2:</b> The <tt>x</tt>, <tt>y</tt> and <tt>radius</tt> must not
5351      * wrap since that has not been implemented yet within MongoDB.
5352      * </p>
5353      * <p>
5354      * Only a single {@link #within} comparison can be used. Calling multiple
5355      * <tt>withinXXX(...)</tt> methods overwrites previous values. In addition
5356      * any {@link #equals(boolean) equals(...)} condition is removed since no
5357      * equality operator is supported by MongoDB.
5358      * </p>
5359      * 
5360      * @param x
5361      *            The X coordinate for the center of the circle.
5362      * @param y
5363      *            The Y coordinate for the center of the circle.
5364      * @param radius
5365      *            The radius of the circle.
5366      * @param uniqueDocs
5367      *            Controls if documents are returned multiple times for multiple
5368      *            matching conditions.
5369      * @return The condition builder for chaining method calls.
5370      * @deprecated {@code $uniqueDocs} was removed in MongoDB 2.6. This method
5371      *             will not be removed until two releases after the MongoDB 2.6
5372      *             release (e.g. 2.10 if the releases are 2.8 and 2.10).
5373      */
5374     @Deprecated
5375     public ConditionBuilder withinOnSphere(final double x, final double y,
5376             final double radius, final boolean uniqueDocs) {
5377         myEqualsComparison = null;
5378 
5379         final DocumentBuilder builder = BuilderFactory.start();
5380         final ArrayBuilder box = builder
5381                 .pushArray(GeospatialOperator.SPHERICAL_CIRCLE);
5382         box.pushArray().addDouble(x).addDouble(y);
5383         box.addDouble(radius);
5384         builder.addBoolean(GeospatialOperator.UNIQUE_DOCS_MODIFIER, uniqueDocs);
5385 
5386         myOtherComparisons.put(GeospatialOperator.WITHIN, new DocumentElement(
5387                 GeospatialOperator.WITHIN.getToken(), builder.build()));
5388 
5389         return this;
5390     }
5391 
5392     /**
5393      * Geospatial query for documents whose field is within the specified
5394      * bounding circular region on a sphere.
5395      * <p>
5396      * <b>NOTE:</b> The <tt>x</tt> must be within the range [-180, 180) and the
5397      * <tt>y</tt> values must be in the range (-90, 90) or the query will throw
5398      * a {@link QueryFailedException}.
5399      * </p>
5400      * <p>
5401      * <b>NOTE 2:</b> The <tt>x</tt>, <tt>y</tt> and <tt>radius</tt> must not
5402      * wrap since that has not been implemented yet within MongoDB.
5403      * </p>
5404      * <p>
5405      * Only a single {@link #within} comparison can be used. Calling multiple
5406      * <tt>withinXXX(...)</tt> methods overwrites previous values. In addition
5407      * any {@link #equals(boolean) equals(...)} condition is removed since no
5408      * equality operator is supported by MongoDB.
5409      * </p>
5410      * 
5411      * @param x
5412      *            The X coordinate for the center of the circle.
5413      * @param y
5414      *            The Y coordinate for the center of the circle.
5415      * @param radius
5416      *            The radius of the circle.
5417      * @return The condition builder for chaining method calls.
5418      */
5419     public ConditionBuilder withinOnSphere(final int x, final int y,
5420             final int radius) {
5421         myEqualsComparison = null;
5422 
5423         final DocumentBuilder builder = BuilderFactory.start();
5424         final ArrayBuilder box = builder
5425                 .pushArray(GeospatialOperator.SPHERICAL_CIRCLE);
5426         box.pushArray().addInteger(x).addInteger(y);
5427         box.addInteger(radius);
5428 
5429         myOtherComparisons.put(GeospatialOperator.WITHIN, new DocumentElement(
5430                 GeospatialOperator.WITHIN.getToken(), builder.build()));
5431 
5432         return this;
5433     }
5434 
5435     /**
5436      * Geospatial query for documents whose field is within the specified
5437      * bounding circular region on a sphere.
5438      * <p>
5439      * <b>NOTE:</b> The <tt>x</tt> must be within the range [-180, 180) and the
5440      * <tt>y</tt> values must be in the range (-90, 90) or the query will throw
5441      * a {@link QueryFailedException}.
5442      * </p>
5443      * <p>
5444      * <b>NOTE 2:</b> The <tt>x</tt>, <tt>y</tt> and <tt>radius</tt> must not
5445      * wrap since that has not been implemented yet within MongoDB.
5446      * </p>
5447      * <p>
5448      * Only a single {@link #within} comparison can be used. Calling multiple
5449      * <tt>withinXXX(...)</tt> methods overwrites previous values. In addition
5450      * any {@link #equals(boolean) equals(...)} condition is removed since no
5451      * equality operator is supported by MongoDB.
5452      * </p>
5453      * 
5454      * @param x
5455      *            The X coordinate for the center of the circle.
5456      * @param y
5457      *            The Y coordinate for the center of the circle.
5458      * @param radius
5459      *            The radius of the circle.
5460      * @param uniqueDocs
5461      *            Controls if documents are returned multiple times for multiple
5462      *            matching conditions.
5463      * @return The condition builder for chaining method calls.
5464      * @deprecated {@code $uniqueDocs} was removed in MongoDB 2.6. This method
5465      *             will not be removed until two releases after the MongoDB 2.6
5466      *             release (e.g. 2.10 if the releases are 2.8 and 2.10).
5467      */
5468     @Deprecated
5469     public ConditionBuilder withinOnSphere(final int x, final int y,
5470             final int radius, final boolean uniqueDocs) {
5471         myEqualsComparison = null;
5472 
5473         final DocumentBuilder builder = BuilderFactory.start();
5474         final ArrayBuilder box = builder
5475                 .pushArray(GeospatialOperator.SPHERICAL_CIRCLE);
5476         box.pushArray().addInteger(x).addInteger(y);
5477         box.addInteger(radius);
5478         builder.addBoolean(GeospatialOperator.UNIQUE_DOCS_MODIFIER, uniqueDocs);
5479 
5480         myOtherComparisons.put(GeospatialOperator.WITHIN, new DocumentElement(
5481                 GeospatialOperator.WITHIN.getToken(), builder.build()));
5482 
5483         return this;
5484     }
5485 
5486     /**
5487      * Geospatial query for documents whose field is within the specified
5488      * bounding circular region on a sphere.
5489      * <p>
5490      * <b>NOTE:</b> The <tt>x</tt> must be within the range [-180, 180) and the
5491      * <tt>y</tt> values must be in the range (-90, 90) or the query will throw
5492      * a {@link QueryFailedException}.
5493      * </p>
5494      * <p>
5495      * <b>NOTE 2:</b> The <tt>x</tt>, <tt>y</tt> and <tt>radius</tt> must not
5496      * wrap since that has not been implemented yet within MongoDB.
5497      * </p>
5498      * <p>
5499      * Only a single {@link #within} comparison can be used. Calling multiple
5500      * <tt>withinXXX(...)</tt> methods overwrites previous values. In addition
5501      * any {@link #equals(boolean) equals(...)} condition is removed since no
5502      * equality operator is supported by MongoDB.
5503      * </p>
5504      * 
5505      * @param x
5506      *            The X coordinate for the center of the circle.
5507      * @param y
5508      *            The Y coordinate for the center of the circle.
5509      * @param radius
5510      *            The radius of the circle.
5511      * @return The condition builder for chaining method calls.
5512      */
5513     public ConditionBuilder withinOnSphere(final long x, final long y,
5514             final long radius) {
5515         myEqualsComparison = null;
5516 
5517         final DocumentBuilder builder = BuilderFactory.start();
5518         final ArrayBuilder box = builder
5519                 .pushArray(GeospatialOperator.SPHERICAL_CIRCLE);
5520         box.pushArray().addLong(x).addLong(y);
5521         box.addLong(radius);
5522 
5523         myOtherComparisons.put(GeospatialOperator.WITHIN, new DocumentElement(
5524                 GeospatialOperator.WITHIN.getToken(), builder.build()));
5525 
5526         return this;
5527     }
5528 
5529     /**
5530      * Geospatial query for documents whose field is within the specified
5531      * bounding circular region on a sphere.
5532      * <p>
5533      * <b>NOTE:</b> The <tt>x</tt> must be within the range [-180, 180) and the
5534      * <tt>y</tt> values must be in the range (-90, 90) or the query will throw
5535      * a {@link QueryFailedException}.
5536      * </p>
5537      * <p>
5538      * <b>NOTE 2:</b> The <tt>x</tt>, <tt>y</tt> and <tt>radius</tt> must not
5539      * wrap since that has not been implemented yet within MongoDB.
5540      * </p>
5541      * <p>
5542      * Only a single {@link #within} comparison can be used. Calling multiple
5543      * <tt>withinXXX(...)</tt> methods overwrites previous values. In addition
5544      * any {@link #equals(boolean) equals(...)} condition is removed since no
5545      * equality operator is supported by MongoDB.
5546      * </p>
5547      * 
5548      * @param x
5549      *            The X coordinate for the center of the circle.
5550      * @param y
5551      *            The Y coordinate for the center of the circle.
5552      * @param radius
5553      *            The radius of the circle.
5554      * @param uniqueDocs
5555      *            Controls if documents are returned multiple times for multiple
5556      *            matching conditions.
5557      * @return The condition builder for chaining method calls.
5558      * @deprecated {@code $uniqueDocs} was removed in MongoDB 2.6. This method
5559      *             will not be removed until two releases after the MongoDB 2.6
5560      *             release (e.g. 2.10 if the releases are 2.8 and 2.10).
5561      */
5562     @Deprecated
5563     public ConditionBuilder withinOnSphere(final long x, final long y,
5564             final long radius, final boolean uniqueDocs) {
5565         myEqualsComparison = null;
5566 
5567         final DocumentBuilder builder = BuilderFactory.start();
5568         final ArrayBuilder box = builder
5569                 .pushArray(GeospatialOperator.SPHERICAL_CIRCLE);
5570         box.pushArray().addLong(x).addLong(y);
5571         box.addLong(radius);
5572         builder.addBoolean(GeospatialOperator.UNIQUE_DOCS_MODIFIER, uniqueDocs);
5573 
5574         myOtherComparisons.put(GeospatialOperator.WITHIN, new DocumentElement(
5575                 GeospatialOperator.WITHIN.getToken(), builder.build()));
5576 
5577         return this;
5578     }
5579 
5580     /**
5581      * Returns the element representing the current state of this fields
5582      * condition.
5583      * 
5584      * @return The element for the condition which may be <code>null</code> if
5585      *         no condition has been set.
5586      */
5587     /* package */Element buildFieldCondition() {
5588         if (!myOtherComparisons.isEmpty()) {
5589             return new DocumentElement(myFieldName, myOtherComparisons.values());
5590         }
5591 
5592         // Note - This may be null.
5593         return myEqualsComparison;
5594     }
5595 }