forked from Automattic/mongoose
-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathfaq.html
More file actions
341 lines (306 loc) · 27.7 KB
/
faq.html
File metadata and controls
341 lines (306 loc) · 27.7 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
<!DOCTYPE html><html lang="en"><head><meta charset="utf-8"><meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=no"><title>Mongoose v5.1.8-pre: FAQ</title><link rel="apple-touch-icon" sizes="57x57" href="images/favicon/apple-icon-57x57.png"><link rel="apple-touch-icon" sizes="60x60" href="images/favicon/apple-icon-60x60.png"><link rel="apple-touch-icon" sizes="72x72" href="images/favicon/apple-icon-72x72.png"><link rel="apple-touch-icon" sizes="76x76" href="images/favicon/apple-icon-76x76.png"><link rel="apple-touch-icon" sizes="114x114" href="images/favicon/apple-icon-114x114.png"><link rel="apple-touch-icon" sizes="120x120" href="images/favicon/apple-icon-120x120.png"><link rel="apple-touch-icon" sizes="144x144" href="images/favicon/apple-icon-144x144.png"><link rel="apple-touch-icon" sizes="152x152" href="images/favicon/apple-icon-152x152.png"><link rel="apple-touch-icon" sizes="180x180" href="images/favicon/apple-icon-180x180.png"><link rel="icon" type="image/png" sizes="192x192" href="images/favicon/android-icon-192x192.png"><link rel="icon" type="image/png" sizes="32x32" href="images/favicon/favicon-32x32.png"><link rel="icon" type="image/png" sizes="96x96" href="images/favicon/favicon-96x96.png"><link rel="icon" type="image/png" sizes="16x16" href="images/favicon/favicon-16x16.png"><link rel="stylesheet" href="https://unpkg.com/[email protected]/build/pure-min.css" integrity="sha384-nn4HPE8lTHyVtfCBi5yW9d20FjT8BJwUXyWZT9InLYax14RDjBj46LmSztkmNP9w" crossorigin="anonymous"><link rel="stylesheet" href="https://fonts.googleapis.com/css?family=Open+Sans"><link rel="stylesheet" href="/docs/css/github.css"><link rel="stylesheet" href="/docs/css/mongoose5.css"><link rel="apple-touch-icon" sizes="57x57" href="images/favicon/apple-icon-57x57.png"><link rel="apple-touch-icon" sizes="60x60" href="images/favicon/apple-icon-60x60.png"><link rel="apple-touch-icon" sizes="72x72" href="images/favicon/apple-icon-72x72.png"><link rel="apple-touch-icon" sizes="76x76" href="images/favicon/apple-icon-76x76.png"><link rel="apple-touch-icon" sizes="114x114" href="images/favicon/apple-icon-114x114.png"><link rel="apple-touch-icon" sizes="120x120" href="images/favicon/apple-icon-120x120.png"><link rel="apple-touch-icon" sizes="144x144" href="images/favicon/apple-icon-144x144.png"><link rel="apple-touch-icon" sizes="152x152" href="images/favicon/apple-icon-152x152.png"><link rel="apple-touch-icon" sizes="180x180" href="images/favicon/apple-icon-180x180.png"><link rel="icon" type="image/png" sizes="192x192" href="images/favicon/android-icon-192x192.png"><link rel="icon" type="image/png" sizes="32x32" href="images/favicon/favicon-32x32.png"><link rel="icon" type="image/png" sizes="96x96" href="images/favicon/favicon-96x96.png"><link rel="icon" type="image/png" sizes="16x16" href="images/favicon/favicon-16x16.png"><link rel="manifest" href="images/favicon/manifest.json"><meta name="msapplication-TileColor" content="#ffffff"><meta name="msapplication-TileImage" content="images/favicon/ms-icon-144x144.png"><meta name="theme-color" content="#ffffff"><style>hr {
display: block;
margin-top: 40px;
margin-bottom: 40px;
border: 0px;
height: 1px;
background-color: #232323;
width: 100%;
}
</style></head><body><div id="layout"><div id="mobile-menu"><a id="menuLink" href="#menu" class="menu-link"><span></span></a><div id="mobile-logo-container"><a href="/"><img id="logo" src="/docs/images/mongoose5_62x30_transparent.png"><span class="logo-text">mongoose</span></a></div></div><div id="menu"><div class="pure-menu"><div id="logo-container" class="pure-menu-heading"><a href="/"><img id="logo" src="/docs/images/mongoose5_62x30_transparent.png"><span class="logo-text">mongoose</span></a></div><ul class="pure-menu-list"><li class="pure-menu-horizontal pure-menu-item pure-menu-has-children pure-menu-allow-hover version"><a href="#" class="pure-menu-link">Version 5.1.8-pre</a><ul class="pure-menu-children"><li class="pure-menu-item"><a href="/docs/4.x" class="pure-menu-link">Version 4.13.14</a></li><li class="pure-menu-item"><a href="/docs/3.8.x" class="pure-menu-link">Version 3.8.40</a></li></ul></li><li class="pure-menu-item"><a href="/docs/index.html" class="pure-menu-link">Quick Start</a></li><li class="pure-menu-item"><a href="/docs/guides.html" class="pure-menu-link">Guides</a></li><li class="pure-menu-item sub-item"><a href="/docs/guide.html" class="pure-menu-link">Schemas</a></li><li class="pure-menu-item sub-item"><a href="/docs/schematypes.html" class="pure-menu-link">SchemaTypes</a></li><li class="pure-menu-item sub-item"><a href="/docs/connections.html" class="pure-menu-link">Connections</a></li><li class="pure-menu-item sub-item"><a href="/docs/models.html" class="pure-menu-link">Models</a></li><li class="pure-menu-item sub-item"><a href="/docs/documents.html" class="pure-menu-link">Documents</a></li><li class="pure-menu-item sub-item"><a href="/docs/subdocs.html" class="pure-menu-link">Subdocuments</a></li><li class="pure-menu-item sub-item"><a href="/docs/queries.html" class="pure-menu-link">Queries</a></li><li class="pure-menu-item sub-item"><a href="/docs/validation.html" class="pure-menu-link">Validation</a></li><li class="pure-menu-item sub-item"><a href="/docs/middleware.html" class="pure-menu-link">Middleware</a></li><li class="pure-menu-item sub-item"><a href="/docs/populate.html" class="pure-menu-link">Populate</a></li><li class="pure-menu-item sub-item"><a href="/docs/discriminators.html" class="pure-menu-link">Discriminators</a></li><li class="pure-menu-item sub-item"><a href="/docs/plugins.html" class="pure-menu-link">Plugins</a></li><li class="pure-menu-item"><a href="/docs/api.html" class="pure-menu-link">API</a></li><li class="pure-menu-item sub-item"><a href="/docs/api.html#mongoose_Mongoose" class="pure-menu-link">Mongoose</a></li><li class="pure-menu-item sub-item"><a href="/docs/api.html#Schema" class="pure-menu-link">Schema</a></li><li class="pure-menu-item sub-item"><a href="/docs/api.html#Connection" class="pure-menu-link">Connection</a></li><li class="pure-menu-item sub-item"><a href="/docs/api.html#Document" class="pure-menu-link">Document</a></li><li class="pure-menu-item sub-item"><a href="/docs/api.html#Model" class="pure-menu-link">Model</a></li><li class="pure-menu-item sub-item"><a href="/docs/api.html#Query" class="pure-menu-link">Query</a></li><li class="pure-menu-item sub-item"><a href="/docs/api.html#Aggregate" class="pure-menu-link">Aggregate</a></li><li class="pure-menu-item sub-item"><a href="/docs/api.html#Schematype" class="pure-menu-link">SchemaType</a></li><li class="pure-menu-item sub-item"><a href="/docs/api.html#Virtualtype" class="pure-menu-link">VirtualType</a></li><li class="pure-menu-item"><a href="/docs/compatibility.html" class="pure-menu-link">Version Compatibility</a></li><li class="pure-menu-item"><a href="/docs/faq.html" class="pure-menu-link">FAQ</a></li><li class="carbon-ad"><script async type="text/javascript" src="//cdn.carbonads.com/carbon.js?zoneid=1673&serve=C6AILKT&placement=mongoosejscom" id="_carbonads_js"></script></li></ul></div></div><div class="container"><div id="content"><h2 id="faq">FAQ</h2>
<p><strong>Q</strong>. Why don't my changes to arrays get saved when I update an element
directly?</p>
<pre><code class="lang-javascript">doc.array[<span class="hljs-number">3</span>] = <span class="hljs-string">'changed'</span>;
doc.save();
</code></pre>
<p><strong>A</strong>. Mongoose doesn't create getters/setters for array indexes; without
them mongoose never gets notified of the change and so doesn't know to
persist the new value. The work-around is to use
<a href="./api.html#types_array_MongooseArray.set">MongooseArray#set</a> available
in <strong>Mongoose >= 3.2.0</strong>.</p>
<pre><code class="lang-javascript"><span class="hljs-comment">// 3.2.0</span>
doc.array.set(<span class="hljs-number">3</span>, <span class="hljs-string">'changed'</span>);
doc.save();
<span class="hljs-comment">// if running a version less than 3.2.0, you must mark the array modified before saving.</span>
doc.array[<span class="hljs-number">3</span>] = <span class="hljs-string">'changed'</span>;
doc.markModified(<span class="hljs-string">'array'</span>);
doc.save();
</code></pre>
<hr id="unique-doesnt-work" />
<p><strong>Q</strong>. I declared a schema property as <code>unique</code> but I can still save
duplicates. What gives?</p>
<p><strong>A</strong>. Mongoose doesn't handle <code>unique</code> on its own: <code>{ name: { type: String, unique: true } }</code>
is just a shorthand for creating a <a href="https://docs.mongodb.com/manual/core/index-unique/">MongoDB unique index on <code>name</code></a>.
For example, if MongoDB doesn't already have a unique index on <code>name</code>, the below code will not error despite the fact that <code>unique</code> is true.</p>
<pre><code class="lang-javascript"><span class="hljs-keyword">var</span> schema = <span class="hljs-keyword">new</span> mongoose.Schema({
name: { type: <span class="hljs-built_in">String</span>, unique: <span class="hljs-literal">true</span> }
});
<span class="hljs-keyword">var</span> Model = db.model(<span class="hljs-string">'Test'</span>, schema);
Model.create([{ name: <span class="hljs-string">'Val'</span> }, { name: <span class="hljs-string">'Val'</span> }], <span class="hljs-function"><span class="hljs-keyword">function</span>(<span class="hljs-params">err</span>) </span>{
<span class="hljs-built_in">console</span>.log(err); <span class="hljs-comment">// No error, unless index was already built</span>
});
</code></pre>
<p>However, if you wait for the index to build using the <code>Model.on('index')</code> event, attempts to save duplicates will correctly error.</p>
<pre><code class="lang-javascript"><span class="hljs-keyword">var</span> schema = <span class="hljs-keyword">new</span> mongoose.Schema({
name: { type: <span class="hljs-built_in">String</span>, unique: <span class="hljs-literal">true</span> }
});
<span class="hljs-keyword">var</span> Model = db.model(<span class="hljs-string">'Test'</span>, schema);
Model.on(<span class="hljs-string">'index'</span>, <span class="hljs-function"><span class="hljs-keyword">function</span>(<span class="hljs-params">err</span>) </span>{ <span class="hljs-comment">// <-- Wait for model's indexes to finish</span>
assert.ifError(err);
Model.create([{ name: <span class="hljs-string">'Val'</span> }, { name: <span class="hljs-string">'Val'</span> }], <span class="hljs-function"><span class="hljs-keyword">function</span>(<span class="hljs-params">err</span>) </span>{
<span class="hljs-built_in">console</span>.log(err);
});
});
<span class="hljs-comment">// Promise based alternative. `init()` returns a promise that resolves</span>
<span class="hljs-comment">// when the indexes have finished building successfully. The `init()`</span>
<span class="hljs-comment">// function is idempotent, so don't worry about triggering an index rebuild.</span>
Model.init().then(<span class="hljs-function"><span class="hljs-keyword">function</span>(<span class="hljs-params"></span>) </span>{
assert.ifError(err);
Model.create([{ name: <span class="hljs-string">'Val'</span> }, { name: <span class="hljs-string">'Val'</span> }], <span class="hljs-function"><span class="hljs-keyword">function</span>(<span class="hljs-params">err</span>) </span>{
<span class="hljs-built_in">console</span>.log(err);
});
});
</code></pre>
<p>MongoDB persists indexes, so you only need to rebuild indexes if you're starting
with a fresh database or you ran <code>db.dropDatabase()</code>. In a production environment,
you should [create your indexes using the MongoDB shell])(<a href="https://docs.mongodb.com/manual/reference/method/db.collection.createIndex/">https://docs.mongodb.com/manual/reference/method/db.collection.createIndex/</a>)
rather than relying on mongoose to do it for you. The <code>unique</code> option for schemas is
convenient for development and documentation, but mongoose is <em>not</em> an index management solution.</p>
<hr id="nested-properties" />
<p><strong>Q</strong>. When I have a nested property in a schema, mongoose adds empty objects by default. Why?</p>
<pre><code class="lang-javascript"><span class="hljs-keyword">var</span> schema = <span class="hljs-keyword">new</span> mongoose.Schema({
nested: {
prop: <span class="hljs-built_in">String</span>
}
});
<span class="hljs-keyword">var</span> Model = db.model(<span class="hljs-string">'Test'</span>, schema);
<span class="hljs-comment">// The below prints `{ _id: /* ... */, nested: {} }`, mongoose assigns</span>
<span class="hljs-comment">// `nested` to an empty object `{}` by default.</span>
<span class="hljs-built_in">console</span>.log(<span class="hljs-keyword">new</span> Model());
</code></pre>
<p><strong>A</strong>. This is a performance optimization. These empty objects are not saved
to the database, nor are they in the result <code>toObject()</code>, nor do they show
up in <code>JSON.stringify()</code> output unless you turn off the <a href="./guide.html#minimize"><code>minimize</code> option</a>.</p>
<p>The reason for this behavior is that Mongoose's change detection
and getters/setters are based on <a href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/defineProperty"><code>Object.defineProperty()</code></a>.
In order to support change detection on nested properties without incurring
the overhead of running <code>Object.defineProperty()</code> every time a document is created,
mongoose defines properties on the <code>Model</code> prototype when the model is compiled.
Because mongoose needs to define getters and setters for <code>nested.prop</code>, <code>nested</code>
must always be defined as an object on a mongoose document, even if <code>nested</code>
is undefined on the underlying <a href="./guide.html#minimize">POJO</a>.</p>
<hr id="arrow-functions" />
<p><strong>Q</strong>. I'm using an arrow function for a <a href="./guide.html#virtuals">virtual</a>, <a href="./middleware.html">middleware</a>, <a href="./api.html#schematype_SchemaType-get">getter</a>/<a href="./api.html#schematype_SchemaType-set">setter</a>, or <a href="./guide.html#methods">method</a> and the value of <code>this</code> is wrong.</p>
<p><strong>A</strong>. Arrow functions <a href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Functions/Arrow_functions#No_binding_of_this">handle the <code>this</code> keyword much differently than conventional functions</a>.
Mongoose getters/setters depend on <code>this</code> to give you access to the document that you're writing to, but this functionality does not work with arrow functions. Do <strong>not</strong> use arrow functions for mongoose getters/setters unless do not intend to access the document in the getter/setter.</p>
<pre><code class="lang-javascript"><span class="hljs-comment">// Do **NOT** use arrow functions as shown below unless you're certain</span>
<span class="hljs-comment">// that's what you want. If you're reading this FAQ, odds are you should</span>
<span class="hljs-comment">// just be using a conventional function.</span>
<span class="hljs-keyword">var</span> schema = <span class="hljs-keyword">new</span> mongoose.Schema({
propWithGetter: {
type: <span class="hljs-built_in">String</span>,
get: v => {
<span class="hljs-comment">// Will **not** be the doc, do **not** use arrow functions for getters/setters</span>
<span class="hljs-built_in">console</span>.log(<span class="hljs-keyword">this</span>);
<span class="hljs-keyword">return</span> v;
}
}
});
<span class="hljs-comment">// `this` will **not** be the doc, do **not** use arrow functions for methods</span>
schema.method.arrowMethod = () => <span class="hljs-keyword">this</span>;
schema.virtual(<span class="hljs-string">'virtualWithArrow'</span>).get(() => {
<span class="hljs-comment">// `this` will **not** be the doc, do **not** use arrow functions for virtuals</span>
<span class="hljs-built_in">console</span>.log(<span class="hljs-keyword">this</span>);
});
</code></pre>
<hr id="type-key">
<p><strong>Q</strong>. I have an embedded property named <code>type</code> like this:</p>
<pre><code class="lang-javascript"><span class="hljs-keyword">const</span> holdingSchema = <span class="hljs-keyword">new</span> Schema({
<span class="hljs-comment">// You might expect `asset` to be an object that has 2 properties,</span>
<span class="hljs-comment">// but unfortunately `type` is special in mongoose so mongoose</span>
<span class="hljs-comment">// interprets this schema to mean that `asset` is a string</span>
asset: {
type: <span class="hljs-built_in">String</span>,
ticker: <span class="hljs-built_in">String</span>
}
});
</code></pre>
<p>But mongoose gives me a CastError telling me that it can't cast an object
to a string when I try to save a <code>Holding</code> with an <code>asset</code> object. Why
is this?</p>
<pre><code class="lang-javascript">Holding.create({ asset: { type: <span class="hljs-string">'stock'</span>, ticker: <span class="hljs-string">'MDB'</span> } }).catch(error => {
<span class="hljs-comment">// Cast to String failed for value "{ type: 'stock', ticker: 'MDB' }" at path "asset"</span>
<span class="hljs-built_in">console</span>.error(error);
});
</code></pre>
<p><strong>A</strong>. The <code>type</code> property is special in mongoose, so when you say
<code>type: String</code>, mongoose interprets it as a type declaration. In the
above schema, mongoose thinks <code>asset</code> is a string, not an object. Do
this instead:</p>
<pre><code class="lang-javascript"><span class="hljs-keyword">const</span> holdingSchema = <span class="hljs-keyword">new</span> Schema({
<span class="hljs-comment">// This is how you tell mongoose you mean `asset` is an object with</span>
<span class="hljs-comment">// a string property `type`, as opposed to telling mongoose that `asset`</span>
<span class="hljs-comment">// is a string.</span>
asset: {
type: { type: <span class="hljs-built_in">String</span> },
ticker: <span class="hljs-built_in">String</span>
}
});
</code></pre>
<hr id="populate_sort_order" />
<p><strong>Q</strong>. I'm populating a nested property under an array like the below code:</p>
<pre><code class="lang-javascript"> <span class="hljs-keyword">new</span> Schema({
arr: [{
child: { ref: <span class="hljs-string">'OtherModel'</span>, type: Schema.Types.ObjectId }
}]
});
</code></pre>
<p><code>.populate({ path: 'arr.child', options: { sort: 'name' } })</code> won't sort
by <code>arr.child.name</code>?</p>
<p><strong>A</strong>. See <a href="https://github.com/Automattic/mongoose/issues/2202">this GitHub issue</a>. It's a known issue but one that's exceptionally difficult to fix.</p>
<hr id="model_functions_hanging" />
<p><strong>Q</strong>. All function calls on my models hang, what am I doing wrong?</p>
<p><strong>A</strong>. By default, mongoose will buffer your function calls until it can
connect to MongoDB. Read the <a href="./connections.html#buffering">buffering section of the connection docs</a>
for more information.</p>
<hr id="enable_debugging" />
<p><strong>Q</strong>. How can I enable debugging?</p>
<p><strong>A</strong>. Set the <code>debug</code> option to <code>true</code>:</p>
<pre><code class="lang-javascript">mongoose.set(<span class="hljs-string">'debug'</span>, <span class="hljs-literal">true</span>)
</code></pre>
<p>All executed collection methods will log output of their arguments to your
console.</p>
<hr id="callback_never_executes" />
<p><strong>Q</strong>. My <code>save()</code> callback never executes. What am I doing wrong?</p>
<p><strong>A</strong>. All <code>collection</code> actions (insert, remove, queries, etc.) are queued
until the <code>connection</code> opens. It is likely that an error occurred while
attempting to connect. Try adding an error handler to your connection.</p>
<pre><code class="lang-javascript"><span class="hljs-comment">// if connecting on the default mongoose connection</span>
mongoose.connect(..);
mongoose.connection.on(<span class="hljs-string">'error'</span>, handleError);
<span class="hljs-comment">// if connecting on a separate connection</span>
<span class="hljs-keyword">var</span> conn = mongoose.createConnection(..);
conn.on(<span class="hljs-string">'error'</span>, handleError);
</code></pre>
<p>If you want to opt out of mongoose's buffering mechanism across your entire
application, set the global <code>bufferCommands</code> option to false:</p>
<pre><code class="lang-javascript">mongoose.set(<span class="hljs-string">'bufferCommands'</span>, <span class="hljs-literal">false</span>);
</code></pre>
<hr id="creating_connections" />
<p><strong>Q</strong>. Should I create/destroy a new connection for each database operation?</p>
<p><strong>A</strong>. No. Open your connection when your application starts up and leave
it open until the application shuts down.</p>
<hr id="overwrite-model-error" />
<p><strong>Q</strong>. Why do I get "OverwriteModelError: Cannot overwrite .. model once
compiled" when I use nodemon / a testing framework?</p>
<p><strong>A</strong>. <code>mongoose.model('ModelName', schema)</code> requires 'ModelName' to be
unique, so you can access the model by using <code>mongoose.model('ModelName')</code>.
If you put <code>mongoose.model('ModelName', schema);</code> in a
<a href="https://mochajs.org/#hooks">mocha <code>beforeEach()</code> hook</a>, this code will
attempt to create a new model named 'ModelName' before <strong>every</strong> test,
and so you will get an error. Make sure you only create a new model with
a given name <strong>once</strong>. If you need to create multiple models with the
same name, create a new connection and bind the model to the connection.</p>
<pre><code class="lang-javascript"><span class="hljs-keyword">var</span> mongoose = <span class="hljs-built_in">require</span>(<span class="hljs-string">'mongoose'</span>);
<span class="hljs-keyword">var</span> connection = mongoose.createConnection(..);
<span class="hljs-comment">// use mongoose.Schema</span>
<span class="hljs-keyword">var</span> kittySchema = mongoose.Schema({ name: <span class="hljs-built_in">String</span> });
<span class="hljs-comment">// use connection.model</span>
<span class="hljs-keyword">var</span> Kitten = connection.model(<span class="hljs-string">'Kitten'</span>, kittySchema);
</code></pre>
<hr id="array-defaults" />
<p><strong>Q</strong>. How can I change mongoose's default behavior of initializing an array
path to an empty array so that I can require real data on document creation?</p>
<p><strong>A</strong>. You can set the default of the array to a function that returns null.</p>
<pre><code class="lang-javascript"><span class="hljs-keyword">const</span> CollectionSchema = <span class="hljs-keyword">new</span> Schema({
field1: {
type: [<span class="hljs-built_in">String</span>],
<span class="hljs-keyword">default</span>: <span class="hljs-keyword">void</span> <span class="hljs-number">0</span>
}
});
</code></pre>
<hr id="aggregate-casting" />
<p><strong>Q</strong>. Why does my aggregate $match fail to return the document that my find query
returns when working with dates?</p>
<p><strong>A</strong>. Mongoose does not cast aggregation pipeline stages because with $project,
$group, etc. the type of a property may change during the aggregation. If you want
to query by date using the aggregation framework, you're responsible for ensuring
that you're passing in a valid date.</p>
<hr id="date_changes" />
<p><strong>Q</strong>. Why don't in-place modifications to date objects
(e.g. <code>date.setMonth(1);</code>) get saved?</p>
<pre><code class="lang-javascript">doc.createdAt.setDate(<span class="hljs-number">2011</span>, <span class="hljs-number">5</span>, <span class="hljs-number">1</span>);
doc.save(); <span class="hljs-comment">// createdAt changes won't get saved!</span>
</code></pre>
<p><strong>A</strong>. Mongoose currently doesn't watch for in-place updates to date
objects. If you have need for this feature, feel free to discuss on
<a href="https://github.com/Automattic/mongoose/issues/3738">this GitHub issue</a>.
There are several workarounds:</p>
<pre><code class="lang-javascript">doc.createdAt.setDate(<span class="hljs-number">2011</span>, <span class="hljs-number">5</span>, <span class="hljs-number">1</span>);
doc.markModified(<span class="hljs-string">'createdAt'</span>);
doc.save(); <span class="hljs-comment">// Works</span>
doc.createdAt = <span class="hljs-keyword">new</span> <span class="hljs-built_in">Date</span>(<span class="hljs-number">2011</span>, <span class="hljs-number">5</span>, <span class="hljs-number">1</span>).setHours(<span class="hljs-number">4</span>);
doc.save(); <span class="hljs-comment">// Works</span>
</code></pre>
<hr id="parallel_saves" />
<p><strong>Q</strong>. Why does calling <code>save()</code> multiple times on the same document in parallel only let
the first save call succeed and return ParallelSaveErrors for the rest?</p>
<p><strong>A</strong>. Due to the asynchronous nature of validation and middleware in general, calling
<code>save()</code> multiple times in parallel on the same doc could result in conflicts. For example,
validating, and then subsequently invalidating the same path.</p>
<hr id="add_something" />
<p><strong>Something to add?</strong></p>
<p>If you'd like to contribute to this page, please
<a href="https://github.com/Automattic/mongoose/tree/master/docs/faq.jade">visit it</a>
on github and use the <a href="https://github.com/blog/844-forking-with-the-edit-button">Edit</a> button to send a pull request.</p>
</div></div><script type="text/javascript">!function(name,path,ctx){
var latest,prev=name!=='Keen'&&window.Keen?window.Keen:false;ctx[name]=ctx[name]||{ready:function(fn){var h=document.getElementsByTagName('head')[0],s=document.createElement('script'),w=window,loaded;s.onload=s.onerror=s.onreadystatechange=function(){if((s.readyState&&!(/^c|loade/.test(s.readyState)))||loaded){return}s.onload=s.onreadystatechange=null;loaded=1;latest=w.Keen;if(prev){w.Keen=prev}else{try{delete w.Keen}catch(e){w.Keen=void 0}}ctx[name]=latest;ctx[name].ready(fn)};s.async=1;s.src=path;h.parentNode.insertBefore(s,h)}}
}('KeenAsync','https://d26b395fwzu5fz.cloudfront.net/keen-tracking-1.1.3.min.js',this);
KeenAsync.ready(function(){
// Configure a client instance
var client = new KeenAsync({
projectId: '59aad9cbc9e77c0001ce1b32',
writeKey: '4B38B0046086885E425D368BFAEAD8FD0D4F2DC2FA2F936FDE058D79508AEFAD9886BC020B96520823BB9C8241D9D9BCFDC0EF52E6033BD89D06E4B24FC13AE955896BF443406269A84DD009CEB5862DCEC944874DB2107FD648DA91ADC1E6DE'
});
client.recordEvent('pageView', {
host: window.location.host,
pathname: window.location.pathname,
hash: window.location.hash
});
});</script><script type="text/javascript">(function (window, document) {
var layout = document.getElementById('layout'),
menu = document.getElementById('menu'),
menuLink = document.getElementById('menuLink'),
content = document.getElementById('content');
function toggleClass(element, className) {
var classes = element.className.split(/\s+/),
length = classes.length,
i = 0;
for(; i < length; i++) {
if (classes[i] === className) {
classes.splice(i, 1);
break;
}
}
// The className is not found
if (length === classes.length) {
classes.push(className);
}
element.className = classes.join(' ');
}
function toggleAll(e) {
var active = 'active';
e.preventDefault();
toggleClass(layout, active);
toggleClass(menu, active);
toggleClass(menuLink, active);
}
menuLink.onclick = function (e) {
toggleAll(e);
};
content.onclick = function(e) {
if (menu.className.indexOf('active') !== -1) {
toggleAll(e);
}
};
}(this, this.document));</script></div></body></html>