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