17
17
18
18
namespace MongoDB \Operation ;
19
19
20
- use MongoDB \Driver \Command ;
21
- use MongoDB \Driver \ReadConcern ;
22
- use MongoDB \Driver \ReadPreference ;
23
20
use MongoDB \Driver \Server ;
24
- use MongoDB \Driver \Session ;
25
21
use MongoDB \Driver \Exception \RuntimeException as DriverRuntimeException ;
26
22
use MongoDB \Exception \InvalidArgumentException ;
27
23
use MongoDB \Exception \UnexpectedValueException ;
36
32
*/
37
33
class CountDocuments implements Executable
38
34
{
39
- private static $ wireVersionForCollation = 5 ;
40
- private static $ wireVersionForReadConcern = 4 ;
41
-
42
35
private $ databaseName ;
43
36
private $ collectionName ;
44
37
private $ filter ;
45
- private $ options ;
38
+ private $ aggregateOptions ;
39
+ private $ countOptions ;
40
+ private $ aggregate ;
46
41
47
42
/**
48
43
* Constructs an aggregate command for counting documents
@@ -89,46 +84,22 @@ public function __construct($databaseName, $collectionName, $filter, array $opti
89
84
throw InvalidArgumentException::invalidType ('$filter ' , $ filter , 'array or object ' );
90
85
}
91
86
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
-
100
87
if (isset ($ options ['limit ' ]) && ! is_integer ($ options ['limit ' ])) {
101
88
throw InvalidArgumentException::invalidType ('"limit" option ' , $ options ['limit ' ], 'integer ' );
102
89
}
103
90
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
-
120
91
if (isset ($ options ['skip ' ]) && ! is_integer ($ options ['skip ' ])) {
121
92
throw InvalidArgumentException::invalidType ('"skip" option ' , $ options ['skip ' ], 'integer ' );
122
93
}
123
94
124
- if (isset ($ options ['readConcern ' ]) && $ options ['readConcern ' ]->isDefault ()) {
125
- unset($ options ['readConcern ' ]);
126
- }
127
-
128
95
$ this ->databaseName = (string ) $ databaseName ;
129
96
$ this ->collectionName = (string ) $ collectionName ;
130
97
$ 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 ();
132
103
}
133
104
134
105
/**
@@ -143,20 +114,7 @@ public function __construct($databaseName, $collectionName, $filter, array $opti
143
114
*/
144
115
public function execute (Server $ server )
145
116
{
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 );
160
118
$ allResults = $ cursor ->toArray ();
161
119
162
120
/* 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)
174
132
}
175
133
176
134
/**
177
- * Create the count command document.
178
- *
179
- * @return array
135
+ * @return Aggregate
180
136
*/
181
- private function createCommandDocument ()
137
+ private function createAggregate ()
182
138
{
183
139
$ pipeline = [
184
140
['$match ' => (object ) $ this ->filter ]
185
141
];
186
142
187
- if (isset ($ this ->options ['skip ' ])) {
188
- $ pipeline [] = ['$skip ' => $ this ->options ['skip ' ]];
143
+ if (isset ($ this ->countOptions ['skip ' ])) {
144
+ $ pipeline [] = ['$skip ' => $ this ->countOptions ['skip ' ]];
189
145
}
190
146
191
- if (isset ($ this ->options ['limit ' ])) {
192
- $ pipeline [] = ['$limit ' => $ this ->options ['limit ' ]];
147
+ if (isset ($ this ->countOptions ['limit ' ])) {
148
+ $ pipeline [] = ['$limit ' => $ this ->countOptions ['limit ' ]];
193
149
}
194
150
195
151
$ pipeline [] = ['$group ' => ['_id ' => 1 , 'n ' => ['$sum ' => 1 ]]];
196
152
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 );
241
154
}
242
155
}
0 commit comments