2
2
3
3
namespace MongoDB ;
4
4
5
+ use MongoDB \Driver \BulkWrite ;
5
6
use MongoDB \Driver \Command ;
6
7
use MongoDB \Driver \Cursor ;
7
8
use MongoDB \Driver \Manager ;
8
9
use MongoDB \Driver \Query ;
9
10
use MongoDB \Driver \ReadPreference ;
10
- use MongoDB \Driver \BulkWrite ;
11
+ use MongoDB \Driver \Server ;
11
12
use MongoDB \Driver \WriteConcern ;
13
+ use MongoDB \Exception \InvalidArgumentException ;
14
+ use MongoDB \Exception \UnexpectedTypeException ;
15
+ use MongoDB \Model \IndexInfoIterator ;
16
+ use MongoDB \Model \IndexInfoIteratorIterator ;
17
+ use MongoDB \Model \IndexInput ;
12
18
13
19
class Collection
14
20
{
@@ -244,34 +250,68 @@ public function count(array $filter = array(), array $options = array())
244
250
}
245
251
246
252
/**
247
- * Create a single index in the collection.
253
+ * Create a single index for the collection.
248
254
*
249
255
* @see http://docs.mongodb.org/manual/reference/command/createIndexes/
250
256
* @see http://docs.mongodb.org/manual/reference/method/db.collection.createIndex/
251
- * @param array|object $keys
252
- * @param array $options
257
+ * @see Collection::createIndexes()
258
+ * @param array|object $key Document containing fields mapped to values,
259
+ * which denote order or an index type
260
+ * @param array $options Index options
253
261
* @return string The name of the created index
254
262
*/
255
- public function createIndex ($ keys , array $ options = array ())
263
+ public function createIndex ($ key , array $ options = array ())
256
264
{
257
- // TODO
265
+ return current ( $ this -> createIndexes ( array ( array ( ' key ' => $ key ) + $ options )));
258
266
}
259
267
260
268
/**
261
- * Create multiple indexes in the collection.
269
+ * Create one or more indexes for the collection.
270
+ *
271
+ * Each element in the $indexes array must have a "key" document, which
272
+ * contains fields mapped to an order or type. Other options may follow.
273
+ * For example:
274
+ *
275
+ * $indexes = [
276
+ * // Create a unique index on the "username" field
277
+ * [ 'key' => [ 'username' => 1 ], 'unique' => true ],
278
+ * // Create a 2dsphere index on the "loc" field with a custom name
279
+ * [ 'key' => [ 'loc' => '2dsphere' ], 'name' => 'geo' ],
280
+ * ];
262
281
*
263
- * TODO: decide if $models should be an array of associative arrays, using
264
- * createIndex()'s parameter names as keys, or tuples, using parameters in
265
- * order (e.g. [keys, options]).
282
+ * If the "name" option is unspecified, a name will be generated from the
283
+ * "key" document.
266
284
*
267
285
* @see http://docs.mongodb.org/manual/reference/command/createIndexes/
268
286
* @see http://docs.mongodb.org/manual/reference/method/db.collection.createIndex/
269
- * @param array $models
287
+ * @param array $indexes List of index specifications
270
288
* @return string[] The names of the created indexes
289
+ * @throws InvalidArgumentException if an index specification is invalid
271
290
*/
272
- public function createIndexes (array $ models )
291
+ public function createIndexes (array $ indexes )
273
292
{
274
- // TODO
293
+ if (empty ($ indexes )) {
294
+ return array ();
295
+ }
296
+
297
+ foreach ($ indexes as $ i => $ index ) {
298
+ if ( ! is_array ($ index )) {
299
+ throw new UnexpectedTypeException ($ index , 'array ' );
300
+ }
301
+
302
+ if ( ! isset ($ index ['ns ' ])) {
303
+ $ index ['ns ' ] = $ this ->ns ;
304
+ }
305
+
306
+ $ indexes [$ i ] = new IndexInput ($ index );
307
+ }
308
+
309
+ $ readPreference = new ReadPreference (ReadPreference::RP_PRIMARY );
310
+ $ server = $ this ->manager ->selectServer ($ readPreference );
311
+
312
+ return (FeatureDetection::isSupported ($ server , FeatureDetection::API_CREATEINDEXES_CMD ))
313
+ ? $ this ->createIndexesCommand ($ server , $ indexes )
314
+ : $ this ->createIndexesLegacy ($ server , $ indexes );
275
315
}
276
316
277
317
/**
@@ -354,11 +394,24 @@ public function drop()
354
394
* @see http://docs.mongodb.org/manual/reference/method/db.collection.dropIndex/
355
395
* @param string $indexName
356
396
* @return Cursor
357
- * @throws InvalidArgumentException if "*" is specified
397
+ * @throws InvalidArgumentException if $indexName is an empty string or "*"
358
398
*/
359
399
public function dropIndex ($ indexName )
360
400
{
361
- // TODO
401
+ $ indexName = (string ) $ indexName ;
402
+
403
+ if ($ indexName === '' ) {
404
+ throw new InvalidArgumentException ('Index name cannot be empty ' );
405
+ }
406
+
407
+ if ($ indexName === '* ' ) {
408
+ throw new InvalidArgumentException ('dropIndexes() must be used to drop multiple indexes ' );
409
+ }
410
+
411
+ $ command = new Command (array ('dropIndexes ' => $ this ->collname , 'index ' => $ indexName ));
412
+ $ readPreference = new ReadPreference (ReadPreference::RP_PRIMARY );
413
+
414
+ return $ this ->manager ->executeCommand ($ this ->dbname , $ command , $ readPreference );
362
415
}
363
416
364
417
/**
@@ -370,7 +423,10 @@ public function dropIndex($indexName)
370
423
*/
371
424
public function dropIndexes ()
372
425
{
373
- // TODO
426
+ $ command = new Command (array ('dropIndexes ' => $ this ->collname , 'index ' => '* ' ));
427
+ $ readPreference = new ReadPreference (ReadPreference::RP_PRIMARY );
428
+
429
+ return $ this ->manager ->executeCommand ($ this ->dbname , $ command , $ readPreference );
374
430
}
375
431
376
432
/**
@@ -949,15 +1005,20 @@ public function insertOne(array $document)
949
1005
}
950
1006
951
1007
/**
952
- * Returns information for all indexes in the collection.
1008
+ * Returns information for all indexes for the collection.
953
1009
*
954
1010
* @see http://docs.mongodb.org/manual/reference/command/listIndexes/
955
1011
* @see http://docs.mongodb.org/manual/reference/method/db.collection.getIndexes/
956
- * @return Cursor
1012
+ * @return IndexInfoIterator
957
1013
*/
958
1014
public function listIndexes ()
959
1015
{
960
- // TODO
1016
+ $ readPreference = new ReadPreference (ReadPreference::RP_PRIMARY );
1017
+ $ server = $ this ->manager ->selectServer ($ readPreference );
1018
+
1019
+ return (FeatureDetection::isSupported ($ server , FeatureDetection::API_LISTINDEXES_CMD ))
1020
+ ? $ this ->listIndexesCommand ($ server )
1021
+ : $ this ->listIndexesLegacy ($ server );
961
1022
}
962
1023
963
1024
/**
@@ -1136,4 +1197,78 @@ protected function _update($filter, $update, $options)
1136
1197
$ bulk ->update ($ filter , $ update , $ options );
1137
1198
return $ this ->manager ->executeBulkWrite ($ this ->ns , $ bulk , $ this ->wc );
1138
1199
}
1200
+
1201
+ /**
1202
+ * Create one or more indexes for the collection using the createIndexes
1203
+ * command.
1204
+ *
1205
+ * @param Server $server
1206
+ * @param IndexInput[] $indexes
1207
+ * @return string[] The names of the created indexes
1208
+ */
1209
+ private function createIndexesCommand (Server $ server , array $ indexes )
1210
+ {
1211
+ $ command = new Command (array (
1212
+ 'createIndexes ' => $ this ->collname ,
1213
+ 'indexes ' => $ indexes ,
1214
+ ));
1215
+ $ server ->executeCommand ($ this ->dbname , $ command );
1216
+
1217
+ return array_map (function (IndexInput $ index ) { return (string ) $ index ; }, $ indexes );
1218
+ }
1219
+
1220
+ /**
1221
+ * Create one or more indexes for the collection by inserting into the
1222
+ * "system.indexes" collection (MongoDB <2.6).
1223
+ *
1224
+ * @param Server $server
1225
+ * @param IndexInput[] $indexes
1226
+ * @return string[] The names of the created indexes
1227
+ */
1228
+ private function createIndexesLegacy (Server $ server , array $ indexes )
1229
+ {
1230
+ $ bulk = new BulkWrite (true );
1231
+
1232
+ foreach ($ indexes as $ index ) {
1233
+ // TODO: Remove this once PHPC-274 is resolved (see: PHPLIB-87)
1234
+ $ bulk ->insert ($ index ->bsonSerialize ());
1235
+ }
1236
+
1237
+ $ server ->executeBulkWrite ($ this ->dbname . '.system.indexes ' , $ bulk );
1238
+
1239
+ return array_map (function (IndexInput $ index ) { return (string ) $ index ; }, $ indexes );
1240
+ }
1241
+
1242
+ /**
1243
+ * Returns information for all indexes for this collection using the
1244
+ * listIndexes command.
1245
+ *
1246
+ * @see http://docs.mongodb.org/manual/reference/command/listIndexes/
1247
+ * @param Server $server
1248
+ * @return IndexInfoIteratorIterator
1249
+ */
1250
+ private function listIndexesCommand (Server $ server )
1251
+ {
1252
+ $ command = new Command (array ('listIndexes ' => $ this ->collname ));
1253
+ $ cursor = $ server ->executeCommand ($ this ->dbname , $ command );
1254
+ $ cursor ->setTypeMap (array ('document ' => 'array ' ));
1255
+
1256
+ return new IndexInfoIteratorIterator ($ cursor );
1257
+ }
1258
+
1259
+ /**
1260
+ * Returns information for all indexes for this collection by querying the
1261
+ * "system.indexes" collection (MongoDB <2.8).
1262
+ *
1263
+ * @param Server $server
1264
+ * @return IndexInfoIteratorIterator
1265
+ */
1266
+ private function listIndexesLegacy (Server $ server )
1267
+ {
1268
+ $ query = new Query (array ('ns ' => $ this ->ns ));
1269
+ $ cursor = $ server ->executeQuery ($ this ->dbname . '.system.indexes ' , $ query );
1270
+ $ cursor ->setTypeMap (array ('document ' => 'array ' ));
1271
+
1272
+ return new IndexInfoIteratorIterator ($ cursor );
1273
+ }
1139
1274
}
0 commit comments