See Release Notes
Long Term Support Release
Differences Between: [Versions 310 and 401] [Versions 311 and 401] [Versions 39 and 401] [Versions 400 and 401]
1 <?php 2 /* 3 * Copyright 2018-present MongoDB, Inc. 4 * 5 * Licensed under the Apache License, Version 2.0 (the "License"); 6 * you may not use this file except in compliance with the License. 7 * You may obtain a copy of the License at 8 * 9 * https://www.apache.org/licenses/LICENSE-2.0 10 * 11 * Unless required by applicable law or agreed to in writing, software 12 * distributed under the License is distributed on an "AS IS" BASIS, 13 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 * See the License for the specific language governing permissions and 15 * limitations under the License. 16 */ 17 18 namespace MongoDB\Operation; 19 20 use MongoDB\Driver\Command; 21 use MongoDB\Driver\Exception\RuntimeException as DriverRuntimeException; 22 use MongoDB\Driver\ReadPreference; 23 use MongoDB\Driver\Server; 24 use MongoDB\Driver\Session; 25 use MongoDB\Exception\InvalidArgumentException; 26 use MongoDB\Exception\UnsupportedException; 27 28 use function current; 29 use function is_array; 30 use function is_string; 31 use function MongoDB\server_supports_feature; 32 33 /** 34 * Operation for the explain command. 35 * 36 * @api 37 * @see \MongoDB\Collection::explain() 38 * @see https://mongodb.com/docs/manual/reference/command/explain/ 39 */ 40 class Explain implements Executable 41 { 42 public const VERBOSITY_ALL_PLANS = 'allPlansExecution'; 43 public const VERBOSITY_EXEC_STATS = 'executionStats'; 44 public const VERBOSITY_QUERY = 'queryPlanner'; 45 46 /** @var integer */ 47 private static $wireVersionForAggregate = 7; 48 49 /** @var string */ 50 private $databaseName; 51 52 /** @var Explainable */ 53 private $explainable; 54 55 /** @var array */ 56 private $options; 57 58 /** 59 * Constructs an explain command for explainable operations. 60 * 61 * Supported options: 62 * 63 * * comment (mixed): BSON value to attach as a comment to this command. 64 * 65 * This is not supported for servers versions < 4.4. 66 * 67 * * readPreference (MongoDB\Driver\ReadPreference): Read preference. 68 * 69 * * session (MongoDB\Driver\Session): Client session. 70 * 71 * * typeMap (array): Type map for BSON deserialization. This will be used 72 * used for the returned command result document. 73 * 74 * * verbosity (string): The mode in which the explain command will be run. 75 * 76 * @param string $databaseName Database name 77 * @param Explainable $explainable Operation to explain 78 * @param array $options Command options 79 * @throws InvalidArgumentException for parameter/option parsing errors 80 */ 81 public function __construct(string $databaseName, Explainable $explainable, array $options = []) 82 { 83 if (isset($options['readPreference']) && ! $options['readPreference'] instanceof ReadPreference) { 84 throw InvalidArgumentException::invalidType('"readPreference" option', $options['readPreference'], ReadPreference::class); 85 } 86 87 if (isset($options['session']) && ! $options['session'] instanceof Session) { 88 throw InvalidArgumentException::invalidType('"session" option', $options['session'], Session::class); 89 } 90 91 if (isset($options['typeMap']) && ! is_array($options['typeMap'])) { 92 throw InvalidArgumentException::invalidType('"typeMap" option', $options['typeMap'], 'array'); 93 } 94 95 if (isset($options['verbosity']) && ! is_string($options['verbosity'])) { 96 throw InvalidArgumentException::invalidType('"verbosity" option', $options['verbosity'], 'string'); 97 } 98 99 $this->databaseName = $databaseName; 100 $this->explainable = $explainable; 101 $this->options = $options; 102 } 103 104 /** 105 * Execute the operation. 106 * 107 * @see Executable::execute() 108 * @return array|object 109 * @throws UnsupportedException if the server does not support explaining the operation 110 * @throws DriverRuntimeException for other driver errors (e.g. connection errors) 111 */ 112 public function execute(Server $server) 113 { 114 if ($this->explainable instanceof Aggregate && ! server_supports_feature($server, self::$wireVersionForAggregate)) { 115 throw UnsupportedException::explainNotSupported(); 116 } 117 118 $cursor = $server->executeCommand($this->databaseName, $this->createCommand($server), $this->createOptions()); 119 120 if (isset($this->options['typeMap'])) { 121 $cursor->setTypeMap($this->options['typeMap']); 122 } 123 124 return current($cursor->toArray()); 125 } 126 127 /** 128 * Create the explain command. 129 */ 130 private function createCommand(Server $server): Command 131 { 132 $cmd = ['explain' => $this->explainable->getCommandDocument($server)]; 133 134 foreach (['comment', 'verbosity'] as $option) { 135 if (isset($this->options[$option])) { 136 $cmd[$option] = $this->options[$option]; 137 } 138 } 139 140 return new Command($cmd); 141 } 142 143 /** 144 * Create options for executing the command. 145 * 146 * @see https://php.net/manual/en/mongodb-driver-server.executecommand.php 147 */ 148 private function createOptions(): array 149 { 150 $options = []; 151 152 if (isset($this->options['readPreference'])) { 153 $options['readPreference'] = $this->options['readPreference']; 154 } 155 156 if (isset($this->options['session'])) { 157 $options['session'] = $this->options['session']; 158 } 159 160 return $options; 161 } 162 163 private function isFindAndModify(Explainable $explainable): bool 164 { 165 if ($explainable instanceof FindAndModify || $explainable instanceof FindOneAndDelete || $explainable instanceof FindOneAndReplace || $explainable instanceof FindOneAndUpdate) { 166 return true; 167 } 168 169 return false; 170 } 171 }
title
Description
Body
title
Description
Body
title
Description
Body
title
Body