Skip to content

Commit f39b752

Browse files
committed
docs(NODE-2329): write upgrade and migration guide
1 parent 131341f commit f39b752

File tree

2 files changed

+155
-114
lines changed

2 files changed

+155
-114
lines changed

docs/CHANGES_4.0.0.md

Lines changed: 117 additions & 114 deletions
Original file line numberDiff line numberDiff line change
@@ -1,71 +1,12 @@
1-
# Changes in 4.x
1+
# Changes in 4.x (and how to migrate!)
22

33
_Hello dear reader, **thank you** for adopting version 4.x of the mongodb driver, from the bottom of our developer hearts we thank you so much for taking the time to upgrade to our latest and greatest offering of a stunning database experience.
44
We hope you enjoy your upgrade experience and this guide gives you all the answers you are searching for.
55
If anything, and we mean anything, hinders you upgrade experience please let us know via [JIRA](https://jira.mongodb.org/browse/NODE).
66
We know breaking changes are hard but they are sometimes for the best.
77
Anyway, enjoy the guide, see you at the end!_
88

9-
## Removed deprecations
10-
11-
- `Collection.prototype.find / findOne options:`
12-
- `fields` - use `projection` instead
13-
- `Collection.prototype.save` - use `insertOne` instead
14-
- `Collection.prototype.dropAllIndexes`
15-
- `Collection.prototype.ensureIndex`
16-
- `Collection.prototype.findAndModify` - use `findOneAndUpdate`/`findOneAndReplace`
17-
- `Collection.prototype.findAndRemove` - use `findOneAndDelete` instead
18-
- `Collection.prototype.parallelCollectionScan`
19-
- `MongoError.create`
20-
- `Topology.destroy`
21-
- `Cursor.prototype.each` - `forEach`
22-
- `Db.prototype.eval`
23-
- `Db.prototype.ensureIndex`
24-
- `Db.prototype.profilingInfo`
25-
- `MongoClient.prototype.logout`
26-
- `MongoClient.prototype.addUser: Creating a user without roles`
27-
- `MongoClient.prototype.connect`
28-
- `Remove MongoClient.isConnected` - calling connect is a no-op if already connected
29-
- `Remove MongoClient.logOut`
30-
31-
## Versioned API
32-
33-
Versioned API is a new feature in MongoDB 5.0 that allows user-selectable API versions, subsets of MongoDB server semantics, to be declared on a client.
34-
During communication with a server, clients with a declared API version will force the server to behave in a manner compatible with the API version.
35-
Declaring an API version on a client can be used to ensure consistent responses from a server, providing long term API stability for an application. The declared API version is applied to all commands run through the client, including those sent through the generic RunCommand helper.
36-
Specifying versioned API options in the command document AND declaring an API version on the client is not supported and will lead to undefined behavior.
37-
38-
### Declare an API version on a client
39-
40-
```javascript
41-
// Declare API version "1" for the client
42-
client = new MongoClient(uri, { serverApi: { version: '1' } });
43-
44-
cursor = client.db('database').collection('coll').find(...);
45-
```
46-
47-
### Strict mode
48-
49-
Declaring a `strict` API version will cause the MongoDB server to reject all commands that are not part of the declared API version. This includes command options and aggregation pipeline stages. For example, the following `find` call would fail because the `tailable` option is not part of version 1:
50-
51-
```javascript
52-
// Declare API version "1" for the client, with strict on
53-
client = new MongoClient(uri, { serverApi: { version: '1', strict: true } });
54-
55-
// Fails with an error
56-
cursor = client.db('database').collection('coll').find({ ... }, { tailable: true });
57-
```
58-
59-
### Deprecation Errors
60-
61-
The `deprecationErrors` option can be used to enable command failures when using functionality that is deprecated from version 1. Note that at the time of this writing, no deprecations in version 1 exist.
62-
63-
```javascript
64-
// Declare API version "1" for the client, with deprecationErrors on
65-
client = new MongoClient(uri, { serverApi: { version: '1', deprecationErrors: true } });
66-
67-
// Note: since API version "1" is the initial version, there are no deprecated commands to provide as an example yet.
68-
```
9+
## Key Changes
6910

7011
### Typescript
7112

@@ -74,9 +15,8 @@ Recently we migrated our BSON library to TypeScript as well, this version of the
7415

7516
#### Community Types users (@types/mongodb)
7617

77-
If you are a user of the community types (@types/mongodb) there will likely be issues adopting the types from our codebase. Unfortunately we could not achieve a one to one match in types due to the details of writing the codebase in Typescript vs definitions for the user layer API.
78-
79-
## Key Changes
18+
If you are a user of the community types (@types/mongodb) there will likely be compilation errors while adopting the types from our codebase.
19+
Unfortunately we could not achieve a one to one match in types due to the details of writing the codebase in Typescript vs definitions for the user layer API along with the breaking changes of this major version. Please let us know if there's anything that is a blocker to upgrading [on JIRA](https://jira.mongodb.org/browse/NODE).
8020

8121
### NodeJS Version
8222

@@ -98,7 +38,7 @@ for await (const doc of cursor) {
9838
}
9939
```
10040

101-
Prior to the this release there was inconsistency surrounding how the cursor would error if a setting like limit was applied after cursor execution had begun, that is now more clear since something like this throws: `Cursor is already initialized`
41+
Prior to the this release there was inconsistency surrounding how the cursor would error if a setting like limit was applied after cursor execution had begun. Now, an error along the lines of: `Cursor is already initialized` is thrown.
10242

10343
#### Stream API
10444

@@ -113,19 +53,52 @@ stream.on("end", () => client.close());
11353

11454
### MongoClientOptions interface
11555

116-
With type hinting users should find that the options passed to a MongoClient are completely enumerated and easily discoverable. We have made a big effort to process all options up front to give early warnings about incompatible settings to get your app up and running correctly quicker!
56+
With type hinting users should find that the options passed to a MongoClient are completely enumerated and easily discoverable.
57+
In 3.x there were options, like `maxPoolSize`, that were only respected when `useUnifiedTopology=true` was enabled, vs `poolSize` when `useUnifiedTopology=false`.
58+
We've de-duped these options and put together some hefty validation to help process all options upfront to give early warnings about incompatible settings in order to help your app get up and running correctly quicker!
59+
60+
#### Unified Topology Only
61+
62+
We internally now only manage a Unified Topology when you connect to your MongoDB.
63+
The [differences are described in detail here](https://mongodb.github.io/node-mongodb-native/3.6/reference/unified-topology/).
64+
65+
Feel free to remove the `useUnifiedTopology` and `useNewUrlParser` options at your leisure, they are no longer used by the driver.
66+
67+
**NOTE:** With the unified topology, in order to connect to replicaSet nodes that have not been initialized you must use the new `directConnection` option.
68+
69+
#### Authentication
70+
71+
Specifying username and password as options are supported in only these two formats:
72+
73+
- `new MongoClient(url, { auth: { username: '', password: '' } })`
74+
- `new MongoClient('mongodb://username:[email protected]')`
11775

11876
#### Check Server Identity Inconsistency
11977

120-
Specifying `checkServerIdentity === false` is different from it being leaving it `undefined`.
121-
3.x intercepted `checkServerIdentity: false` and turned it into a no-op function which is the required way to skip checking the server identity by nodejs. This option is only for testing anyway and it didn't make sense for our library to intercept an option that is exposed directly from nodejs.
78+
Specifying `checkServerIdentity === false` (along with enabling tls) is different from it being leaving it `undefined`.
79+
The 3.x version intercepted `checkServerIdentity: false` and turned it into a no-op function which is the required way to skip checking the server identity by nodejs.
80+
Setting this option to `false` is only for testing anyway as it disables essential verification to TLS.
81+
So it made sense for our library to directly expose the option validation from nodejs.
82+
If you need to test TLS connections without verifying server identity pass in `{ checkServerIdentity: () => {} }`.
12283

123-
### db.collection
84+
#### Kerberos / GSSAPI
12485

125-
No longer supports a strict option which would return an error if the collection does not exist. If you require your application to assert a collection's existence, please use:
86+
`gssapiServiceName` has been removed.
87+
Users should use authMechanismProperties.SERVICE_NAME like so:
88+
89+
- In a URI query param: `?authMechanismProperties=SERVICE_NAME:alternateServiceName`
90+
- Or as an option: `{ authMechanismProperties: { SERVICE_NAME: 'alternateServiceName' } }`
91+
92+
### db.collection no longer accepts a callback
93+
94+
The only option that required the use of the callback was strict mode and that option can still be used in `db.createCollection`.
95+
The strict option would return an error if the collection does not exist.
96+
97+
Another way to assert a collections existence is using this snippet below:
12698

12799
```javascript
128-
const collections = (await db.listCollections({}, { nameOnly: true }).toArray())
100+
const collections = (await db.listCollections({}, { nameOnly: true })
101+
.toArray())
129102
.map(({name}) => name); // map to get string[]
130103
if (!collections.includes(myNewCollectionName)) {
131104
await db.createCollection(myNewCollectionName)
@@ -134,36 +107,26 @@ if (!collections.includes(myNewCollectionName)) {
134107

135108
### BulkWriteError renamed to MongoBulkWriteError
136109

137-
When running a bulk operation that makes writes, depending on your settings, you can encounter write errors. User's testing for `BulkWriteErrors` should be sure to import the new class name `MongoBulkWriteError`.
110+
In 3.x we exported both the names above, we now only export `MongoBulkWriteError`.
111+
Users testing for `BulkWriteError`s should be sure to import the new class name `MongoBulkWriteError`.
138112

139113
### Db no longer emits events
140114

141-
The Db instance is no longer an EventEmitter, all events your application is concerned with can be listened to directly from the MongoClient instance.
115+
The Db instance is no longer an EventEmitter, all events your application is concerned with can be listened to directly from the `MongoClient` instance.
142116

143117
### Collection.group() removed
144118

145-
the collection group helper has been deprecated in MongoDB since 3.4 and is now removed from the Driver. The same functionality can be achieved using the aggregation pipeline's $group operator.
146-
147-
### Authentication
148-
149-
Specifying username and password as options are supported in only these two formats:
119+
The collection `group()` helper has been deprecated in MongoDB since 3.4 and is now removed from the Driver.
120+
The same functionality can be achieved using the aggregation pipeline's `$group` operator.
150121

151-
- `new MongoClient(url, { auth: { username: '', password: '' } })`
152-
- `new MongoClient('mongodb://username:[email protected]')`
122+
### GridStore removed
153123

154-
#### Kerberos / GSSAPI
124+
The deprecated GirdStore API has been removed from the driver.
125+
For more information on GridFS [see the mongodb manual](https://docs.mongodb.com/manual/core/gridfs/).
155126

156-
`gssapiServiceName` has been removed.
157-
Users should use authMechanismProperties.SERVICE_NAME like so:
127+
Below are some snippets that represent equivalent operations:
158128

159-
- In a URI query param: `?authMechanismProperties=SERVICE_NAME:alternateServiceName`
160-
- Or as an option: `{ authMechanismProperties: { SERVICE_NAME: 'alternateServiceName' } }`
161-
162-
### GridStore has been removed
163-
164-
The deprecated GirdStore API has been removed from the driver. You can find migration details here
165-
166-
Equivalencies:
129+
#### Construction
167130

168131
```javascript
169132
// old way
@@ -172,13 +135,15 @@ const gs = new GridStore(db, filename, mode[, options])
172135
const bucket = new GridFSBucket(client.db('test')[, options])
173136
```
174137

138+
#### File seeking
139+
175140
Since GridFSBucket uses NodeJS Stream API you can replicate file seek-ing by using the start and end options creating a downloadStream from your GridFSBucket
176141

177142
```javascript
178143
bucket.openDownloadStreamByName(filename, { start: 23, end: 52 })
179144
```
180145

181-
#### Upload / Download example
146+
#### File Upload & File Download
182147

183148
``` javascript
184149
await client.connect();
@@ -206,40 +171,78 @@ fs.createReadStream(filename)
206171
})
207172
```
208173

209-
GridFSBucket does not need to be closed like GridStore
174+
Notably, **GridFSBucket does not need to be closed like GridStore.**
175+
176+
#### File Deletion
210177

211178
Deleting files hasn't changed much:
212179

213180
```javascript
214-
GridStore.unlink(db, name, callback)
215-
bucket.delete(file_id)
181+
GridStore.unlink(db, name, callback) // Old way
182+
bucket.delete(file_id) // New way!
216183
```
217184

185+
#### Finding File Metadata
186+
218187
File metadata that used to be accessible on the GridStore instance can be found by querying the bucket
219188

220-
```javascript
221-
bucket.find(filter).toArray()
222-
[{
223-
_id: ObjectId,
224-
length: number,
225-
chunkSize: number,
226-
uploadDate: Date,
227-
filename: string,
228-
md5: Binary
229-
}]
189+
```typescript
190+
const fileMetaDataList: GridFSFile[] = bucket.find({}).toArray()
230191
```
231192

232-
For more information on GridFS [see the docs](https://docs.mongodb.com/manual/core/gridfs/).
233-
234-
### Unified Topology Only
235-
236-
We internally now only manage a unifiedTopology when you connect to your MongoDB. The [differences are described in detail here](https://mongodb.github.io/node-mongodb-native/3.6/reference/unified-topology/).
193+
## Intentional Breaking Changes
194+
195+
- [`NODE-3368`](https://jira.mongodb.org/browse/NODE-3368): make name prop on error classes read-only ([#2879](https://github.com/mongodb/node-mongodb-native/pull/2879))
196+
- [`NODE-3291`](https://jira.mongodb.org/browse/NODE-3291): standardize error representation in the driver ([#2824](https://github.com/mongodb/node-mongodb-native/pull/2824))
197+
- [`NODE-3272`](https://jira.mongodb.org/browse/NODE-3272): emit correct event type when SRV Polling ([#2825](https://github.com/mongodb/node-mongodb-native/pull/2825))
198+
- [`NODE-2752`](https://jira.mongodb.org/browse/NODE-2752): remove strict/callback mode from Db.collection helper ([#2817](https://github.com/mongodb/node-mongodb-native/pull/2817))
199+
- [`NODE-1812`](https://jira.mongodb.org/browse/NODE-1812): replace returnOriginal with returnDocument option ([#2803](https://github.com/mongodb/node-mongodb-native/pull/2803))
200+
- [`NODE-3157`](https://jira.mongodb.org/browse/NODE-3157): update find and modify interfaces for 4.0 ([#2799](https://github.com/mongodb/node-mongodb-native/pull/2799))
201+
- [`NODE-2978`](https://jira.mongodb.org/browse/NODE-2978): remove deprecated bulk ops ([#2794](https://github.com/mongodb/node-mongodb-native/pull/2794))
202+
- [`NODE-2317`](https://jira.mongodb.org/browse/NODE-2317): remove deprecated items ([#2740](https://github.com/mongodb/node-mongodb-native/pull/2740)) ([listed below](#removed-deprecations))
203+
- [`NODE-2961`](https://jira.mongodb.org/browse/NODE-2961): clarify empty BulkOperation error message ([#2697](https://github.com/mongodb/node-mongodb-native/pull/2697))
204+
- [`NODE-1709`](https://jira.mongodb.org/browse/NODE-1709): stop emitting topology events from `Db` ([#2251](https://github.com/mongodb/node-mongodb-native/pull/2251))
205+
- [`NODE-2704`](https://jira.mongodb.org/browse/NODE-2704): integrate MongoOptions parser into driver ([#2680](https://github.com/mongodb/node-mongodb-native/pull/2680))
206+
- [`NODE-2757`](https://jira.mongodb.org/browse/NODE-2757): add collation to FindOperators ([#2679](https://github.com/mongodb/node-mongodb-native/pull/2679))
207+
- [`NODE-1722`](https://jira.mongodb.org/browse/NODE-1722): remove top-level write concern options ([#2642](https://github.com/mongodb/node-mongodb-native/pull/2642))
208+
- [`NODE-2602`](https://jira.mongodb.org/browse/NODE-2602): createIndexOp returns string, CreateIndexesOp returns array ([#2666](https://github.com/mongodb/node-mongodb-native/pull/2666))
209+
- [`NODE-2936`](https://jira.mongodb.org/browse/NODE-2936): conform CRUD result types to specification ([#2651](https://github.com/mongodb/node-mongodb-native/pull/2651))
210+
- [`NODE-1487`](https://jira.mongodb.org/browse/NODE-1487): remove deprecated Collection.group helper ([#2609](https://github.com/mongodb/node-mongodb-native/pull/2609))
211+
- [`NODE-2590`](https://jira.mongodb.org/browse/NODE-2590): adds async iterator for custom promises ([#2578](https://github.com/mongodb/node-mongodb-native/pull/2578))
212+
- [`NODE-2458`](https://jira.mongodb.org/browse/NODE-2458): format sort in cursor and in sort builder ([#2573](https://github.com/mongodb/node-mongodb-native/pull/2573))
213+
- [`NODE-2324`](https://jira.mongodb.org/browse/NODE-2324): remove Cursor#transformStream ([#2574](https://github.com/mongodb/node-mongodb-native/pull/2574))
214+
- [`NODE-2816`](https://jira.mongodb.org/browse/NODE-2816): remove deprecated find options ([#2571](https://github.com/mongodb/node-mongodb-native/pull/2571))
215+
- [`NODE-2820`](https://jira.mongodb.org/browse/NODE-2820): pull CursorStream out of Cursor ([#2543](https://github.com/mongodb/node-mongodb-native/pull/2543))
216+
- [`NODE-2320`](https://jira.mongodb.org/browse/NODE-2320): remove deprecated GridFS API ([#2290](https://github.com/mongodb/node-mongodb-native/pull/2290))
217+
- [`NODE-2850`](https://jira.mongodb.org/browse/NODE-2850): only store topology on MongoClient ([#2594](https://github.com/mongodb/node-mongodb-native/pull/2594))
237218

238-
**NOTE:** With the unified topology, in order to connect to replicaSet nodes that have not been initialized you must use the new `directConnection` option.
239-
240-
### Instrument function removal
219+
## Removed deprecations
241220

242-
TODO
221+
- `Collection.prototype.find / findOne options:`
222+
- `fields` - use `projection` instead
223+
- `Collection.prototype.save` - use `insertOne` instead
224+
- `Collection.prototype.dropAllIndexes`
225+
- `Collection.prototype.ensureIndex`
226+
- `Collection.prototype.findAndModify` - use `findOneAndUpdate`/`findOneAndReplace`
227+
- `Collection.prototype.findAndRemove` - use `findOneAndDelete` instead
228+
- `Collection.prototype.parallelCollectionScan`
229+
- `MongoError.create`
230+
- `Topology.destroy`
231+
- `Cursor.prototype.each` - `forEach`
232+
- `Db.prototype.eval`
233+
- `Db.prototype.ensureIndex`
234+
- `Db.prototype.profilingInfo`
235+
- `MongoClient.prototype.logout`
236+
- `MongoClient.prototype.addUser: Creating a user without roles`
237+
- `MongoClient.prototype.connect`
238+
- `Remove MongoClient.isConnected` - calling connect is a no-op if already connected
239+
- `Remove MongoClient.logOut`
240+
- `require('mongodb').instrument`
241+
- Use command monitoring: `client.on('commandStarted', (ev) => {})`
242+
- Top-Level export no longer a function: `typeof require('mongodb') !== 'function'`
243+
- Must construct a MongoClient and call `.connect()` on it.
244+
- No more `Symbol` export, now `BSONSymbol` which is a deprecated BSON type
245+
- No more `connect` export, use `MongoClient` construction
243246

244247
---
245248

0 commit comments

Comments
 (0)