You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
*[`null` is valid for non-required string enums](#null-is-valid-for-non-required-string-enums)
21
+
*[Apply minimize when `save()` updates an existing document](#apply-minimize-when-save-updates-an-existing-document)
22
+
*[Apply base schema paths before discriminator paths](#apply-base-schema-paths-before-discriminator-paths)
23
+
*[Changed behavior for `findOneAndUpdate()` with `orFail()` and upsert](#changed-behavior-for-findoneandupdate-with-orfail-and-upsert)
24
+
*[`create()` waits until all saves are done before throwing any error](#create-waits-until-all-saves-are-done-before-throwing-any-error)
25
+
*[`Model.validate()` returns copy of object](#model-validate-returns-copy-of-object)
20
26
*[Allow `null` For Optional Fields in TypeScript](#allow-null-for-optional-fields-in-typescript)
27
+
*[Infer `distinct()` return types from schema](#infer-distinct-return-types-from-schema)
21
28
22
29
<h2id="removed-rawresult-option-for-findoneandupdate"><ahref="#removed-rawresult-option-for-findoneandupdate">Removed <code>rawResult</code> option for <code>findOneAndUpdate()</code></a></h2>
<h2id="changed-behavior-for-findoneandupdate-with-orfail-and-upsert"><ahref="#changed-behavior-for-findoneandupdate-with-orfail-and-upsert">Changed behavior for <code>findOneAndUpdate()</code> with <code>orFail()</code> and upsert</a></h2>
58
-
59
-
In Mongoose 7, `findOneAndUpdate(filter, update, { upsert: true }).orFail()` would throw a `DocumentNotFoundError` if a new document was upserted.
60
-
In other words, `findOneAndUpdate().orFail()` always threw an error if no document was found, even if a new document was upserted.
`Model.count()` and `Query.prototype.count()` were removed in Mongoose 8. Use `Model.countDocuments()` and `Query.prototype.countDocuments()` instead.
80
+
78
81
<h2id="removed-id-setter"><ahref="#removed-id-setter">Removed id Setter</a></h2>
79
82
80
83
In Mongoose 7.4, Mongoose introduced an `id` setter that made `doc.id = '0'.repeat(24)` equivalent to `doc._id = '0'.repeat(24)`.
81
84
In Mongoose 8, that setter is now removed.
82
85
86
+
<h2id="null-is-valid-for-non-required-string-enums"><ahref="#null-is-valid-for-non-required-string-enums"><code>null</code> is valid for non-required string enums</a></h2>
87
+
88
+
Before Mongoose 8, setting a string path with an `enum` to `null` would lead to a validation error, even if that path wasn't `required`.
89
+
In Mongoose 8, it is valid to set a string path to `null` if `required` is not set, even with `enum`.
90
+
91
+
```javascript
92
+
constschema=newSchema({
93
+
status: {
94
+
type:String,
95
+
enum: ['on', 'off']
96
+
}
97
+
});
98
+
constTest=mongoose.model('Test', schema);
99
+
100
+
// Works fine in Mongoose 8
101
+
// Throws a `ValidationError` in Mongoose 7
102
+
awaitTest.create({ status:null });
103
+
```
104
+
105
+
<h2id="apply-minimize-when-save-updates-an-existing-document"><ahref="#apply-minimize-when-save-updates-an-existing-document">Apply minimize when <code>save()</code> updates an existing document</a></h2>
106
+
107
+
In Mongoose 7, Mongoose would only apply minimize when saving a new document, not when updating an existing document.
108
+
109
+
```javascript
110
+
constschema=newSchema({
111
+
nested: {
112
+
field1:Number
113
+
}
114
+
});
115
+
constTest=mongoose.model('Test', schema);
116
+
117
+
// Both Mongoose 7 and Mongoose 8 strip out empty objects when saving
118
+
// a new document in MongoDB by default
119
+
const { _id } =awaitTest.create({ nested: {} });
120
+
let rawDoc =awaitTest.findById(_id).lean();
121
+
rawDoc.nested; // undefined
122
+
123
+
// Mongoose 8 will also strip out empty objects when saving an
124
+
// existing document in MongoDB
125
+
constdoc=awaitTest.findById(_id);
126
+
doc.nested= {};
127
+
doc.markModified('nested');
128
+
awaitdoc.save();
129
+
130
+
let rawDoc =awaitTest.findById(_id).lean();
131
+
rawDoc.nested; // undefined in Mongoose 8, {} in Mongoose 7
132
+
```
133
+
134
+
<h2id="apply-base-schema-paths-before-discriminator-paths"><ahref="#apply-base-schema-paths-before-discriminator-paths">Apply base schema paths before discriminator paths</a></h2>
135
+
136
+
This means that, in Mongoose 8, getters and setters on discriminator paths run _after_ getters and setters on base paths.
137
+
In Mongoose 7, getters and setters on discriminator paths ran _before_ getters and setters on base paths.
138
+
139
+
```javascript
140
+
141
+
constschema=newSchema({
142
+
name: {
143
+
type:String,
144
+
get(v) {
145
+
console.log('Base schema getter');
146
+
return v;
147
+
}
148
+
}
149
+
});
150
+
151
+
constTest=mongoose.model('Test', schema);
152
+
constD=Test.discriminator('D', newSchema({
153
+
otherProp: {
154
+
type:String,
155
+
get(v) {
156
+
console.log('Discriminator schema getter');
157
+
return v;
158
+
}
159
+
}
160
+
}));
161
+
162
+
constdoc=newD({ name:'test', otherProp:'test' });
163
+
// In Mongoose 8, prints "Base schema getter" followed by "Discriminator schema getter"
164
+
// In Mongoose 7, prints "Discriminator schema getter" followed by "Base schema getter"
165
+
console.log(doc.toObject({ getters:true }));
166
+
```
167
+
168
+
<h2id="changed-behavior-for-findoneandupdate-with-orfail-and-upsert"><ahref="#changed-behavior-for-findoneandupdate-with-orfail-and-upsert">Changed behavior for <code>findOneAndUpdate()</code> with <code>orFail()</code> and upsert</a></h2>
169
+
170
+
In Mongoose 7, `findOneAndUpdate(filter, update, { upsert: true }).orFail()` would throw a `DocumentNotFoundError` if a new document was upserted.
171
+
In other words, `findOneAndUpdate().orFail()` always threw an error if no document was found, even if a new document was upserted.
`findOneAndUpdate().orFail()` now throws a `DocumentNotFoundError` if there's no document returned, rather than if no document was found.
175
+
176
+
<h2id="create-waits-until-all-saves-are-done-before-throwing-any-error"><ahref="#create-waits-until-all-saves-are-done-before-throwing-any-error"><code>create()</code> waits until all saves are done before throwing any error</a></h2>
177
+
178
+
In Mongoose 7, `create()` would immediately throw if any `save()` threw an error by default.
179
+
Mongoose 8 instead waits for all `save()` calls to finish before throwing the first error that occurred.
180
+
So `create()` will throw the same error in both Mongoose 7 and Mongoose 8, Mongoose 8 just may take longer to throw the error.
// In Mongoose 7, there would be 0 documents, because `Test.create()`
202
+
// would throw before 'Badger' and 'Mushroom' are inserted
203
+
// In Mongoose 8, there will be 2 documents. `Test.create()` waits until
204
+
// 'Badger' and 'Mushroom' are inserted before throwing.
205
+
awaitTest.countDocuments();
206
+
```
207
+
208
+
<h2id="model-validate-returns-copy-of-object"><ahref="#model-validate-returns-copy-of-object"><code>Model.validate()</code> returns copy of object</a></h2>
209
+
210
+
In Mongoose 7, `Model.validate()` would potentially modify the passed in object.
211
+
Mongoose 8 instead copies the passed in object first.
212
+
213
+
```javascript
214
+
constschema=newSchema({ answer:Number });
215
+
constTest=mongoose.model('Test', schema);
216
+
217
+
constobj= { answer:'42' };
218
+
constres=Test.validate(obj);
219
+
220
+
typeofobj.answer; // 'string' in Mongoose 8, 'number' in Mongoose 7
221
+
typeofres.answer; // 'number' in both Mongoose 7 and Mongoose 8
222
+
```
223
+
83
224
<h2id="allow-null-for-optional-fields-in-typescript"><ahref="#allow-null-for-optional-fields-in-typescript">Allow <code>null</code> For Optional Fields in TypeScript</a></h2>
84
225
85
226
In Mongoose 8, automatically inferred schema types in TypeScript allow `null` for optional fields.
@@ -95,3 +236,21 @@ const doc = new TestModel();
95
236
// In Mongoose 7, this type is `string | undefined`
96
237
doc.name;
97
238
```
239
+
240
+
<h2id="infer-distinct-return-types-from-schema"><ahref="#infer-distinct-return-types-from-schema">Infer <code>distinct()</code> return types from schema</a></h2>
241
+
242
+
```ts
243
+
interfaceUser {
244
+
name:string;
245
+
email:string;
246
+
avatar?:string;
247
+
}
248
+
const schema =newSchema<User>({
249
+
name: { type: String, required: true },
250
+
email: { type: String, required: true },
251
+
avatar: String
252
+
});
253
+
254
+
// Works in Mongoose 8. Compile error in Mongoose 7.
0 commit comments