/driver-core/src/main/com/mongodb/operation/AggregateExplainOperation.java

https://github.com/mebigfatguy/mongo-java-driver · Java · 206 lines · 123 code · 17 blank · 66 comment · 19 complexity · 854a2c13d44f9bc81498519b704f9d24 MD5 · raw file

  1. /*
  2. * Copyright 2008-present MongoDB, Inc.
  3. *
  4. * Licensed under the Apache License, Version 2.0 (the "License");
  5. * you may not use this file except in compliance with the License.
  6. * You may obtain a copy of the License at
  7. *
  8. * http://www.apache.org/licenses/LICENSE-2.0
  9. *
  10. * Unless required by applicable law or agreed to in writing, software
  11. * distributed under the License is distributed on an "AS IS" BASIS,
  12. * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  13. * See the License for the specific language governing permissions and
  14. * limitations under the License.
  15. */
  16. package com.mongodb.operation;
  17. import com.mongodb.MongoNamespace;
  18. import com.mongodb.async.SingleResultCallback;
  19. import com.mongodb.binding.AsyncReadBinding;
  20. import com.mongodb.binding.ReadBinding;
  21. import com.mongodb.client.model.Collation;
  22. import com.mongodb.connection.AsyncConnection;
  23. import com.mongodb.connection.Connection;
  24. import org.bson.BsonArray;
  25. import org.bson.BsonBoolean;
  26. import org.bson.BsonDocument;
  27. import org.bson.BsonInt64;
  28. import org.bson.BsonString;
  29. import org.bson.BsonValue;
  30. import java.util.List;
  31. import java.util.concurrent.TimeUnit;
  32. import static com.mongodb.assertions.Assertions.isTrueArgument;
  33. import static com.mongodb.assertions.Assertions.notNull;
  34. import static com.mongodb.internal.async.ErrorHandlingResultCallback.errorHandlingCallback;
  35. import static com.mongodb.operation.CommandOperationHelper.IdentityTransformer;
  36. import static com.mongodb.operation.CommandOperationHelper.executeWrappedCommandProtocol;
  37. import static com.mongodb.operation.CommandOperationHelper.executeWrappedCommandProtocolAsync;
  38. import static com.mongodb.operation.OperationHelper.AsyncCallableWithConnection;
  39. import static com.mongodb.operation.OperationHelper.CallableWithConnection;
  40. import static com.mongodb.operation.OperationHelper.LOGGER;
  41. import static com.mongodb.operation.OperationHelper.validateCollation;
  42. import static com.mongodb.operation.OperationHelper.releasingCallback;
  43. import static com.mongodb.operation.OperationHelper.withConnection;
  44. // an operation that executes an explain on an aggregation pipeline
  45. class AggregateExplainOperation implements AsyncReadOperation<BsonDocument>, ReadOperation<BsonDocument> {
  46. private final MongoNamespace namespace;
  47. private final List<BsonDocument> pipeline;
  48. private Boolean allowDiskUse;
  49. private long maxTimeMS;
  50. private Collation collation;
  51. private BsonValue hint;
  52. AggregateExplainOperation(final MongoNamespace namespace, final List<BsonDocument> pipeline) {
  53. this.namespace = notNull("namespace", namespace);
  54. this.pipeline = notNull("pipeline", pipeline);
  55. }
  56. /**
  57. * Enables writing to temporary files. A null value indicates that it's unspecified.
  58. *
  59. * @param allowDiskUse true if writing to temporary files is enabled
  60. * @return this
  61. * @mongodb.driver.manual reference/command/aggregate/ Aggregation
  62. * @mongodb.server.release 2.6
  63. */
  64. public AggregateExplainOperation allowDiskUse(final Boolean allowDiskUse) {
  65. this.allowDiskUse = allowDiskUse;
  66. return this;
  67. }
  68. /**
  69. * Sets the maximum execution time on the server for this operation.
  70. *
  71. * @param maxTime the max time
  72. * @param timeUnit the time unit, which may not be null
  73. * @return this
  74. * @mongodb.driver.manual reference/method/cursor.maxTimeMS/#cursor.maxTimeMS Max Time
  75. */
  76. public AggregateExplainOperation maxTime(final long maxTime, final TimeUnit timeUnit) {
  77. notNull("timeUnit", timeUnit);
  78. this.maxTimeMS = TimeUnit.MILLISECONDS.convert(maxTime, timeUnit);
  79. return this;
  80. }
  81. /**
  82. * Sets the collation options
  83. *
  84. * <p>A null value represents the server default.</p>
  85. * @param collation the collation options to use
  86. * @return this
  87. * @since 3.4
  88. * @mongodb.driver.manual reference/command/aggregate/ Aggregation
  89. * @mongodb.server.release 3.4
  90. */
  91. public AggregateExplainOperation collation(final Collation collation) {
  92. this.collation = collation;
  93. return this;
  94. }
  95. /**
  96. * Returns the hint for which index to use. The default is not to set a hint.
  97. *
  98. * @return the hint
  99. * @since 3.6
  100. * @mongodb.server.release 3.6
  101. */
  102. public BsonDocument getHint() {
  103. if (hint == null) {
  104. return null;
  105. }
  106. if (!hint.isDocument()) {
  107. throw new IllegalArgumentException("Hint is not a BsonDocument please use the #getHintBsonValue() method. ");
  108. }
  109. return hint.asDocument();
  110. }
  111. /**
  112. * Returns the hint BsonValue for which index to use. The default is not to set a hint.
  113. *
  114. * <p>Hints can either be a BsonString or a BsonDocument.</p>
  115. *
  116. * @return the hint
  117. * @since 3.8
  118. * @mongodb.server.release 3.6
  119. */
  120. public BsonValue getHintBsonValue() {
  121. return hint;
  122. }
  123. /**
  124. * Sets the hint for which index to use. A null value means no hint is set.
  125. *
  126. * @param hint the hint
  127. * @return this
  128. * @since 3.6
  129. * @mongodb.server.release 3.6
  130. */
  131. public AggregateExplainOperation hint(final BsonValue hint) {
  132. isTrueArgument("BsonString or BsonDocument", hint == null || hint.isDocument() || hint.isString());
  133. this.hint = hint;
  134. return this;
  135. }
  136. @Override
  137. public BsonDocument execute(final ReadBinding binding) {
  138. return withConnection(binding, new CallableWithConnection<BsonDocument>() {
  139. @Override
  140. public BsonDocument call(final Connection connection) {
  141. validateCollation(connection, collation);
  142. return executeWrappedCommandProtocol(binding, namespace.getDatabaseName(), getCommand(), connection);
  143. }
  144. });
  145. }
  146. @Override
  147. public void executeAsync(final AsyncReadBinding binding, final SingleResultCallback<BsonDocument> callback) {
  148. withConnection(binding, new AsyncCallableWithConnection() {
  149. @Override
  150. public void call(final AsyncConnection connection, final Throwable t) {
  151. SingleResultCallback<BsonDocument> errHandlingCallback = errorHandlingCallback(callback, LOGGER);
  152. if (t != null) {
  153. errHandlingCallback.onResult(null, t);
  154. } else {
  155. final SingleResultCallback<BsonDocument> wrappedCallback = releasingCallback(errHandlingCallback, connection);
  156. validateCollation(connection, collation, new AsyncCallableWithConnection() {
  157. @Override
  158. public void call(final AsyncConnection connection, final Throwable t) {
  159. if (t != null) {
  160. wrappedCallback.onResult(null, t);
  161. } else {
  162. executeWrappedCommandProtocolAsync(binding, namespace.getDatabaseName(), getCommand(),
  163. connection, new IdentityTransformer<BsonDocument>(), wrappedCallback);
  164. }
  165. }
  166. });
  167. }
  168. }
  169. });
  170. }
  171. private BsonDocument getCommand() {
  172. BsonDocument commandDocument = new BsonDocument("aggregate", new BsonString(namespace.getCollectionName()));
  173. commandDocument.put("pipeline", new BsonArray(pipeline));
  174. commandDocument.put("explain", BsonBoolean.TRUE);
  175. if (maxTimeMS > 0) {
  176. commandDocument.put("maxTimeMS", new BsonInt64(maxTimeMS));
  177. }
  178. if (allowDiskUse != null) {
  179. commandDocument.put("allowDiskUse", BsonBoolean.valueOf(allowDiskUse));
  180. }
  181. if (collation != null) {
  182. commandDocument.put("collation", collation.asDocument());
  183. }
  184. if (hint != null) {
  185. commandDocument.put("hint", hint);
  186. }
  187. return commandDocument;
  188. }
  189. }