|
| 1 | +# Enumerating Collections |
| 2 | + |
| 3 | +- Status: Accepted |
| 4 | +- Minimum Server Version: 1.8 |
| 5 | + |
| 6 | +______________________________________________________________________ |
| 7 | + |
| 8 | +## Abstract |
| 9 | + |
| 10 | +A driver can contain a feature to enumerate all collections belonging to a database. This specification defines how |
| 11 | +collections should be enumerated. |
| 12 | + |
| 13 | +## META |
| 14 | + |
| 15 | +The keywords "MUST", "MUST NOT", "REQUIRED", "SHALL", "SHALL NOT", "SHOULD", "SHOULD NOT", "RECOMMENDED", "MAY", and |
| 16 | +"OPTIONAL" in this document are to be interpreted as described in [RFC 2119](https://www.ietf.org/rfc/rfc2119.txt). |
| 17 | + |
| 18 | +## Specification |
| 19 | + |
| 20 | +### Terms |
| 21 | + |
| 22 | +**MongoClient**\ |
| 23 | +Driver object representing a connection to MongoDB. This is the root object of a driver's API and MAY |
| 24 | +be named differently in some drivers. |
| 25 | + |
| 26 | +**Iterable**\ |
| 27 | +An object or data structure that is a sequence of elements that can be iterated over. This spec is |
| 28 | +flexible on what that means as different drivers will have different requirements, types, and idioms. |
| 29 | + |
| 30 | +### listCollections Database Command |
| 31 | + |
| 32 | +The `listCollections` command returns a cursor: |
| 33 | + |
| 34 | +```javascript |
| 35 | +db.runCommand( { listCollections: 1 } ); |
| 36 | +``` |
| 37 | + |
| 38 | +The command also accepts options. |
| 39 | + |
| 40 | +The `filter` option, which acts like a query against the returned collection documents. You can i.e. use the following |
| 41 | +to only list the collections beginning with `test`: |
| 42 | + |
| 43 | +```javascript |
| 44 | +db.runCommand( { listCollections: 1, filter: { name: /^test/ } } ); |
| 45 | +``` |
| 46 | + |
| 47 | +Or to find all capped collections: |
| 48 | + |
| 49 | +```javascript |
| 50 | +db.runCommand( { listCollections: 1, filter: { 'options.capped': true } } ); |
| 51 | +``` |
| 52 | + |
| 53 | +The `cursor.batchSize` option, which allows you to set how many initial collections should be returned as part of the |
| 54 | +cursor specification document that comes back from the server. This first batch is part of the returned structure in the |
| 55 | +`firstBatch` key (see more about return types further on). |
| 56 | + |
| 57 | +The command returns a cursor definition structure: |
| 58 | + |
| 59 | +```javascript |
| 60 | +{ |
| 61 | + cursor: { |
| 62 | + id: <long>, |
| 63 | + ns: <string>, |
| 64 | + firstBatch: [<object>, <object>, ...] |
| 65 | + }, |
| 66 | + ok: 1 |
| 67 | +} |
| 68 | +``` |
| 69 | + |
| 70 | +With the `cursor.id` and `cursor.ns` fields you can retrieve further collection information structures. |
| 71 | + |
| 72 | +The command also returns the field `ok` to signal whether the command was executed successfully. |
| 73 | + |
| 74 | +This will return the first 25 collection descriptions as part of the returned document: |
| 75 | + |
| 76 | +```javascript |
| 77 | +db.runCommand( { listCollections: 1, cursor : { batchSize: 25 } } ); |
| 78 | +``` |
| 79 | + |
| 80 | +MongoDB 4.4 introduced a `comment` option to the `listCollections` database command. This option enables users to |
| 81 | +specify a comment as an arbitrary BSON type to help trace the operation through the database profiler, currentOp and |
| 82 | +logs. The default is to not send a value. If a comment is provided on pre-4.4 servers, the comment should still be |
| 83 | +attached and the driver should rely on the server to provide an error to the user. |
| 84 | + |
| 85 | +Example of usage of the comment option: |
| 86 | + |
| 87 | +```javascript |
| 88 | +db.runCommand({"listCollections": 1, "comment": "hi there"}) |
| 89 | +``` |
| 90 | + |
| 91 | +Any comment set on a `listCollections` command is inherited by any subsequent `getMore` commands run on the same |
| 92 | +`cursor.id` returned from the `listCollections` command. Therefore, drivers MUST NOT attach the comment to subsequent |
| 93 | +getMore commands on a cursor. |
| 94 | + |
| 95 | +#### Return types |
| 96 | + |
| 97 | +The `listCollections` command returns a cursor description. The format that is returned is the same as for any other |
| 98 | +command cursor: |
| 99 | + |
| 100 | +```javascript |
| 101 | +{ |
| 102 | + cursor: { |
| 103 | + id: <long>, |
| 104 | + ns: <string>, |
| 105 | + firstBatch: [<object>, <object>, ...] |
| 106 | + }, |
| 107 | + ok: 1 |
| 108 | +} |
| 109 | +``` |
| 110 | + |
| 111 | +The number of objects in the `firstBatch` field depends on the `cursor.batchSize` option. |
| 112 | + |
| 113 | +Drivers MAY expose methods to return collection names as an array. If your driver already has such a method, its return |
| 114 | +type MUST NOT be changed in order to prevent breaking backwards compatibility. |
| 115 | + |
| 116 | +Drivers SHOULD expose (a) method(s) to return collection information through a cursor, where the information for each |
| 117 | +collection is represented by a single document. |
| 118 | + |
| 119 | +### Driver methods |
| 120 | + |
| 121 | +Drivers SHOULD use the method name `listCollections` for a method that returns all collections with a cursor return |
| 122 | +type. Drivers MAY use an idiomatic variant that fits the language the driver is for. |
| 123 | + |
| 124 | +If a driver already has a method to perform one of the listed tasks, there is no need to change it. Do not break |
| 125 | +backwards compatibility when adding new methods. |
| 126 | + |
| 127 | +All methods: |
| 128 | + |
| 129 | +- SHOULD be on the database object. |
| 130 | +- MUST allow a filter to be passed to include only requested collections. |
| 131 | +- MAY allow the `cursor.batchSize` option to be passed. |
| 132 | +- SHOULD allow the `comment` option to be passed. |
| 133 | +- MUST apply timeouts per the |
| 134 | + [Client Side Operations Timeout](./client-side-operations-timeout/client-side-operations-timeout.md) specification. |
| 135 | + |
| 136 | +All methods that return cursors MUST support the timeout options documented in |
| 137 | +[Client Side Operations Timeout: Cursors](./client-side-operations-timeout/client-side-operations-timeout.md#cursors). |
| 138 | + |
| 139 | +#### Getting Collection Names |
| 140 | + |
| 141 | +Drivers MAY implement a MongoClient method that returns an Iterable of strings, where each string corresponds to a |
| 142 | +collection name. This method SHOULD be named `listCollectionNames`. |
| 143 | + |
| 144 | +MongoDB 4.0 introduced a `nameOnly` boolean option to the `listCollections` database command, which limits the command |
| 145 | +result to only include collection names. NOTE: `nameOnly` is applied before any filter is applied. |
| 146 | + |
| 147 | +Example return: |
| 148 | + |
| 149 | +```javascript |
| 150 | +[ |
| 151 | + "me", |
| 152 | + "oplog.rs", |
| 153 | + "replset.minvalid", |
| 154 | + "startup_log", |
| 155 | + "system.indexes", |
| 156 | + "system.replset" |
| 157 | +] |
| 158 | +``` |
| 159 | + |
| 160 | +Server version between 2.7.6 (inclusive) and 4.0 (exclusive) do not support the `nameOnly` option for the |
| 161 | +`listCollections` command and will ignore it without raising an error. Therefore, drivers MUST always specify the |
| 162 | +`nameOnly` option when they only intend to access collection names from the `listCollections` command result, except |
| 163 | +drivers MUST NOT set `nameOnly` if a filter specifies any keys other than `name`. |
| 164 | + |
| 165 | +MongoDB 4.0 also added an `authorizedCollections` boolean option to the `listCollections` command, which can be used to |
| 166 | +limit the command result to only include collections the user is authorized to use. Drivers MAY allow users to set the |
| 167 | +`authorizedCollections` option on the `listCollectionNames` method. |
| 168 | + |
| 169 | +#### Getting Full Collection Information |
| 170 | + |
| 171 | +Drivers MAY implement a method to return the full `name/options` pairs that are returned from both `listCollections` (in |
| 172 | +the `res.cursor.firstBatch` field, and subsequent retrieved documents through getmore on the cursor constructed from |
| 173 | +`res.cursor.ns` and `res.cursor.id`), and the query result for `system.namespaces`. |
| 174 | + |
| 175 | +The returned result for each variant MUST be equivalent, and each collection that is returned MUST use the field names |
| 176 | +`name` and `options`. |
| 177 | + |
| 178 | +In MongoDB 4.4, the `ns` field was removed from the index specifications, so the index specification included in the |
| 179 | +`idIndex` field of the collection information will no longer contain an `ns` field. |
| 180 | + |
| 181 | +- For drivers that report those index specifications in the form of documents or dictionaries, no special handling is |
| 182 | + necessary, but any documentation of the contents of the documents/dictionaries MUST indicate that the `ns` field will |
| 183 | + no longer be present in MongoDB 4.4+. If the contents of the documents/dictionaries are undocumented, then no special |
| 184 | + mention of the `ns` field is necessary. |
| 185 | +- For drivers that report those index specifications in the form of statically defined models, the driver MUST manually |
| 186 | + populate the `ns` field of the models with the appropriate namespace if the server does not report it in the |
| 187 | + `listCollections` command response. The `ns` field is not required to be a part of the models, however. |
| 188 | + |
| 189 | +Example return (a cursor which returns documents, not a simple array): |
| 190 | + |
| 191 | +```javascript |
| 192 | +{ |
| 193 | + "name" : "me", "options" : { "flags" : 1 } |
| 194 | +}, |
| 195 | +{ |
| 196 | + "name" : "oplog.rs", "options" : { "capped" : true, "size" : 10485760, "autoIndexId" : false } |
| 197 | +}, |
| 198 | +{ |
| 199 | + "name" : "replset.minvalid", "options" : { "flags" : 1 } |
| 200 | +}, |
| 201 | +{ |
| 202 | + "name" : "startup_log", "options" : { "capped" : true, "size" : 10485760 } |
| 203 | +}, |
| 204 | +{ |
| 205 | + "name" : "system.indexes", "options" : { } |
| 206 | +}, |
| 207 | +{ |
| 208 | + "name" : "system.replset", "options" : { "flags" : 1 } |
| 209 | +} |
| 210 | +``` |
| 211 | + |
| 212 | +When returning this information as a cursor, a driver SHOULD use the method name `listCollections` or an idiomatic |
| 213 | +variant. |
| 214 | + |
| 215 | +Drivers MAY allow the `nameOnly` and `authorizedCollections` options to be passed when executing the `listCollections` |
| 216 | +command for this method. |
| 217 | + |
| 218 | +#### Returning a List of Collection Objects |
| 219 | + |
| 220 | +Drivers MAY implement a method that returns a collection object for each returned collection, if the driver has such a |
| 221 | +concept. This method MAY be named `listMongoCollections`. |
| 222 | + |
| 223 | +Example return (in PHP, but abbreviated): |
| 224 | + |
| 225 | +```javascript |
| 226 | +array(6) { |
| 227 | + [0] => class MongoCollection#6 { } |
| 228 | + [1] => class MongoCollection#7 { } |
| 229 | + [2] => class MongoCollection#8 { } |
| 230 | + [3] => class MongoCollection#9 { } |
| 231 | + [4] => class MongoCollection#10 { } |
| 232 | + [5] => class MongoCollection#11 { } |
| 233 | +} |
| 234 | +``` |
| 235 | + |
| 236 | +Drivers MUST specify true for the `nameOnly` option when executing the `listCollections` command for this method, except |
| 237 | +drivers MUST NOT set `nameOnly` if a filter specifies any keys other than `name`. |
| 238 | + |
| 239 | +Drivers MAY allow the `authorizedCollections` option to be passed when executing the `listCollections` command for this |
| 240 | +method |
| 241 | + |
| 242 | +#### Replica Sets |
| 243 | + |
| 244 | +- `listCollections` can be run on a secondary node. |
| 245 | +- Querying `system.indexes` on a secondary node requires secondaryOk to be set. |
| 246 | +- Drivers MUST run `listCollections` on the primary node when in a replica set topology, unless directly connected to a |
| 247 | + secondary node in Single topology. |
| 248 | + |
| 249 | +## Test Plan |
| 250 | + |
| 251 | +### Configurations |
| 252 | + |
| 253 | +- standalone node |
| 254 | +- replica set primary node |
| 255 | +- replica set secondary node |
| 256 | +- mongos node |
| 257 | + |
| 258 | +### Preparation |
| 259 | + |
| 260 | +For each of the configurations: |
| 261 | + |
| 262 | +- Create a (new) database |
| 263 | +- Create a collection and a capped collection |
| 264 | +- Create an index on each of the two collections |
| 265 | +- Insert at least one document in each of the two collections |
| 266 | + |
| 267 | +### Tests |
| 268 | + |
| 269 | +- Run the driver's method that returns a list of collection names (e.g. `listCollectionNames()`): |
| 270 | + - verify that *all* collection names are represented in the result |
| 271 | + - verify that there are no duplicate collection names |
| 272 | + - there are no returned collections that do not exist |
| 273 | + - there are no returned collections containing an '$' |
| 274 | +- Run the driver's method that returns a list of collection names (e.g. `listCollectionNames()`), pass a filter of |
| 275 | + `{ 'options.capped': true }`, and: |
| 276 | + - verify that *only* names of capped collections are represented in the result |
| 277 | + - verify that there are no duplicate collection names |
| 278 | + - there are no returned collections that do not exist |
| 279 | + - there are no returned collections containing an '$' |
| 280 | + |
| 281 | +## Backwards Compatibility |
| 282 | + |
| 283 | +There should be no backwards compatibility concerns. This SPEC merely deals with how to enumerate collections in future |
| 284 | +versions of MongoDB. |
| 285 | + |
| 286 | +## Reference Implementation |
| 287 | + |
| 288 | +The shell implements the first algorithm for falling back if the `listCollections` command does not exist |
| 289 | +(<https://github.com/mongodb/mongo/blob/f32ba54f971c045fb589fe4c3a37da77dc486cee/src/mongo/shell/db.js#L550>). |
| 290 | + |
| 291 | +## Changelog |
| 292 | + |
| 293 | +- 2024-07-26: Migrated from reStructuredText to Markdown. Drop description of behavior for MongoDB 2.x servers. |
| 294 | + |
| 295 | +- 2022-10-05: Remove spec front matter and reformat changelog. |
| 296 | + |
| 297 | +- 2022-09-15: Clarify the behavior of `comment` on pre-4.4 servers. |
| 298 | + |
| 299 | +- 2022-02-01: Add `comment` option to `listCollections` command. |
| 300 | + |
| 301 | +- 2022-01-20: Require that timeouts be applied per the client-side operations\ |
| 302 | + timeout spec. |
| 303 | + |
| 304 | +- 2021-12-17: Support `authorizedCollections` option in `listCollections`\ |
| 305 | + command. |
| 306 | + |
| 307 | +- 2021-04-22: Update to use secondaryOk. |
| 308 | + |
| 309 | +- 2020-03-18: MongoDB 4.4 no longer includes `ns` field in `idIndex` field\ |
| 310 | + for `listCollections` responses. |
| 311 | + |
| 312 | +- 2019-03-21: The method that returns a list of collection names should be named\ |
| 313 | + `listCollectionNames`. The method that |
| 314 | + returns a list of collection objects may be named `listMongoCollections`. |
| 315 | + |
| 316 | +- 2018-07-03: Clarify that `nameOnly` must not be used with filters other than\ |
| 317 | + `name`. |
| 318 | + |
| 319 | +- 2018-05-18: Support `nameOnly` option in `listCollections` command. |
| 320 | + |
| 321 | +- 2017-09-27: Clarify reason for filtering collection names containing '$'. |
| 322 | + |
| 323 | +- 2015-01-14: Clarify trimming of database name. Put preferred method name for\ |
| 324 | + listing collections with a cursor as |
| 325 | + return value. |
| 326 | + |
| 327 | +- 2014-12-18: Update with the server change to return a cursor for\ |
| 328 | + `listCollections`. |
0 commit comments