1717
1818namespace MongoDB \Operation ;
1919
20- use MongoDB \Driver \Command ;
21- use MongoDB \Driver \ReadConcern ;
22- use MongoDB \Driver \ReadPreference ;
2320use MongoDB \Driver \Server ;
24- use MongoDB \Driver \Session ;
2521use MongoDB \Driver \Exception \RuntimeException as DriverRuntimeException ;
2622use MongoDB \Exception \InvalidArgumentException ;
2723use MongoDB \Exception \UnexpectedValueException ;
3632 */
3733class CountDocuments implements Executable
3834{
39- private static $ wireVersionForCollation = 5 ;
40- private static $ wireVersionForReadConcern = 4 ;
41-
4235 private $ databaseName ;
4336 private $ collectionName ;
4437 private $ filter ;
45- private $ options ;
38+ private $ aggregateOptions ;
39+ private $ countOptions ;
40+ private $ aggregate ;
4641
4742 /**
4843 * Constructs an aggregate command for counting documents
@@ -89,46 +84,22 @@ public function __construct($databaseName, $collectionName, $filter, array $opti
8984 throw InvalidArgumentException::invalidType ('$filter ' , $ filter , 'array or object ' );
9085 }
9186
92- if (isset ($ options ['collation ' ]) && ! is_array ($ options ['collation ' ]) && ! is_object ($ options ['collation ' ])) {
93- throw InvalidArgumentException::invalidType ('"collation" option ' , $ options ['collation ' ], 'array or object ' );
94- }
95-
96- if (isset ($ options ['hint ' ]) && ! is_string ($ options ['hint ' ]) && ! is_array ($ options ['hint ' ]) && ! is_object ($ options ['hint ' ])) {
97- throw InvalidArgumentException::invalidType ('"hint" option ' , $ options ['hint ' ], 'string or array or object ' );
98- }
99-
10087 if (isset ($ options ['limit ' ]) && ! is_integer ($ options ['limit ' ])) {
10188 throw InvalidArgumentException::invalidType ('"limit" option ' , $ options ['limit ' ], 'integer ' );
10289 }
10390
104- if (isset ($ options ['maxTimeMS ' ]) && ! is_integer ($ options ['maxTimeMS ' ])) {
105- throw InvalidArgumentException::invalidType ('"maxTimeMS" option ' , $ options ['maxTimeMS ' ], 'integer ' );
106- }
107-
108- if (isset ($ options ['readConcern ' ]) && ! $ options ['readConcern ' ] instanceof ReadConcern) {
109- throw InvalidArgumentException::invalidType ('"readConcern" option ' , $ options ['readConcern ' ], ReadConcern::class);
110- }
111-
112- if (isset ($ options ['readPreference ' ]) && ! $ options ['readPreference ' ] instanceof ReadPreference) {
113- throw InvalidArgumentException::invalidType ('"readPreference" option ' , $ options ['readPreference ' ], ReadPreference::class);
114- }
115-
116- if (isset ($ options ['session ' ]) && ! $ options ['session ' ] instanceof Session) {
117- throw InvalidArgumentException::invalidType ('"session" option ' , $ options ['session ' ], Session::class);
118- }
119-
12091 if (isset ($ options ['skip ' ]) && ! is_integer ($ options ['skip ' ])) {
12192 throw InvalidArgumentException::invalidType ('"skip" option ' , $ options ['skip ' ], 'integer ' );
12293 }
12394
124- if (isset ($ options ['readConcern ' ]) && $ options ['readConcern ' ]->isDefault ()) {
125- unset($ options ['readConcern ' ]);
126- }
127-
12895 $ this ->databaseName = (string ) $ databaseName ;
12996 $ this ->collectionName = (string ) $ collectionName ;
13097 $ this ->filter = $ filter ;
131- $ this ->options = $ options ;
98+
99+ $ this ->aggregateOptions = array_intersect_key ($ options , ['collation ' => 1 , 'hint ' => 1 , 'maxTimeMS ' => 1 , 'readConcern ' => 1 , 'readPreference ' => 1 , 'session ' => 1 ]);
100+ $ this ->countOptions = array_intersect_key ($ options , ['limit ' => 1 , 'skip ' => 1 ]);
101+
102+ $ this ->aggregate = $ this ->createAggregate ();
132103 }
133104
134105 /**
@@ -143,20 +114,7 @@ public function __construct($databaseName, $collectionName, $filter, array $opti
143114 */
144115 public function execute (Server $ server )
145116 {
146- if (isset ($ this ->options ['collation ' ]) && ! \MongoDB \server_supports_feature ($ server , self ::$ wireVersionForCollation )) {
147- throw UnsupportedException::collationNotSupported ();
148- }
149-
150- if (isset ($ this ->options ['readConcern ' ]) && ! \MongoDB \server_supports_feature ($ server , self ::$ wireVersionForReadConcern )) {
151- throw UnsupportedException::readConcernNotSupported ();
152- }
153-
154- $ inTransaction = isset ($ this ->options ['session ' ]) && $ this ->options ['session ' ]->isInTransaction ();
155- if ($ inTransaction && isset ($ this ->options ['readConcern ' ])) {
156- throw UnsupportedException::readConcernNotSupportedInTransaction ();
157- }
158-
159- $ cursor = $ server ->executeReadCommand ($ this ->databaseName , new Command ($ this ->createCommandDocument ()), $ this ->createOptions ());
117+ $ cursor = $ this ->aggregate ->execute ($ server );
160118 $ allResults = $ cursor ->toArray ();
161119
162120 /* If there are no documents to count, the aggregation pipeline has no items to group, and
@@ -174,69 +132,24 @@ public function execute(Server $server)
174132 }
175133
176134 /**
177- * Create the count command document.
178- *
179- * @return array
135+ * @return Aggregate
180136 */
181- private function createCommandDocument ()
137+ private function createAggregate ()
182138 {
183139 $ pipeline = [
184140 ['$match ' => (object ) $ this ->filter ]
185141 ];
186142
187- if (isset ($ this ->options ['skip ' ])) {
188- $ pipeline [] = ['$skip ' => $ this ->options ['skip ' ]];
143+ if (isset ($ this ->countOptions ['skip ' ])) {
144+ $ pipeline [] = ['$skip ' => $ this ->countOptions ['skip ' ]];
189145 }
190146
191- if (isset ($ this ->options ['limit ' ])) {
192- $ pipeline [] = ['$limit ' => $ this ->options ['limit ' ]];
147+ if (isset ($ this ->countOptions ['limit ' ])) {
148+ $ pipeline [] = ['$limit ' => $ this ->countOptions ['limit ' ]];
193149 }
194150
195151 $ pipeline [] = ['$group ' => ['_id ' => 1 , 'n ' => ['$sum ' => 1 ]]];
196152
197- $ cmd = [
198- 'aggregate ' => $ this ->collectionName ,
199- 'pipeline ' => $ pipeline ,
200- 'cursor ' => (object ) [],
201- ];
202-
203- if (isset ($ this ->options ['collation ' ])) {
204- $ cmd ['collation ' ] = (object ) $ this ->options ['collation ' ];
205- }
206-
207- if (isset ($ this ->options ['hint ' ])) {
208- $ cmd ['hint ' ] = is_array ($ this ->options ['hint ' ]) ? (object ) $ this ->options ['hint ' ] : $ this ->options ['hint ' ];
209- }
210-
211- if (isset ($ this ->options ['maxTimeMS ' ])) {
212- $ cmd ['maxTimeMS ' ] = $ this ->options ['maxTimeMS ' ];
213- }
214-
215- return $ cmd ;
216- }
217-
218- /**
219- * Create options for executing the command.
220- *
221- * @see http://php.net/manual/en/mongodb-driver-server.executereadcommand.php
222- * @return array
223- */
224- private function createOptions ()
225- {
226- $ options = [];
227-
228- if (isset ($ this ->options ['readConcern ' ])) {
229- $ options ['readConcern ' ] = $ this ->options ['readConcern ' ];
230- }
231-
232- if (isset ($ this ->options ['readPreference ' ])) {
233- $ options ['readPreference ' ] = $ this ->options ['readPreference ' ];
234- }
235-
236- if (isset ($ this ->options ['session ' ])) {
237- $ options ['session ' ] = $ this ->options ['session ' ];
238- }
239-
240- return $ options ;
153+ return new Aggregate ($ this ->databaseName , $ this ->collectionName , $ pipeline , $ this ->aggregateOptions );
241154 }
242155}
0 commit comments