-
-
Notifications
You must be signed in to change notification settings - Fork 3.8k
/
subdocs.html
49 lines (44 loc) · 7.91 KB
/
subdocs.html
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
<!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 SubDocuments v3.3.1</title><link href="http://fonts.googleapis.com/css?family=Anonymous+Pro:400,700|Droid+Sans+Mono|Open+Sans:400,700|Linden+Hill|Quattrocento:400,700|News+Cycle:400,700|Antic+Slab|Cabin+Condensed:400,700" rel="stylesheet" type="text/css"><link href="/docs/css/default.css" rel="stylesheet" type="text/css"><link href="/docs/css/guide.css" rel="stylesheet" type="text/css"></head><body><a id="forkbanner" href="http://github.com/learnboost/mongoose"><img style="position: absolute; top: 0; right: 0; border: 0;" src="https://s3.amazonaws.com/github/ribbons/forkme_right_gray_6d6d6d.png" alt="Fork me on GitHub"></a><div id="links"><div id="header"><h1><a href="../index.html"><div class="mongoose">Mongoose</div></a></h1></div><ul><li class="home"><a href="../index.html">home</a></li><li class="faq"><a href="./faq.html">FAQ</a></li><li class="plugins"><a href="http://plugins.mongoosejs.com">plugins</a></li><li class="changelog"><a href="http://github.com/learnboost/mongoose/tree/master/History.md">change log</a></li><li class="support"><a href="../index.html#support">support</a></li><li class="fork"><a href="http://github.com/learnboost/mongoose">fork</a></li><li class="guide"><a href="./guide.html">guide</a><ul><li class="double"><a href="./guide.html">schemas</a><ul><li class="schematypes"><a href="./schematypes.html"><span>schema</span>types</a></li></ul></li><li><a href="./models.html">models</a></li><li class="double"><a href="./documents.html">documents</a><ul><li class="subdocs"><a href="./subdocs.html">sub docs</a></li></ul></li><li><a href="./queries.html">queries</a></li><li><a href="./validation.html">validation</a></li><li><a href="./middleware.html">middleware</a></li><li><a href="./populate.html">population</a></li><li><a href="./connections.html">connections</a></li><li><a href="./plugins.html">plugins</a></li><li><a href="https://github.com/LearnBoost/mongoose/blob/master/CONTRIBUTING.md">contributing</a></li><li><a href="./migration.html">migrating from 2.x</a></li></ul></li><li class="api"><a href="./api.html">API docs</a></li><li class="quickstart"><a href="./index.html">quick start</a></li><li class="contrib"><a href="http://github.com/learnboost/mongoose/contributors">contributors</a></li><li class="prior"><a href="./prior.html">prior releases</a></li></ul></div><div id="content"><div class="module"><h2>Sub Docs</h2><p><a href="./api.html#types-embedded-js">Sub-documents</a> are docs with schemas of their own which are elements of a parents document array:</p><pre><code class="javascript"><span class="keyword">var</span> childSchema = <span class="keyword">new</span> Schema({ name: <span class="string">'string'</span> });
<span class="keyword">var</span> parentSchema = <span class="keyword">new</span> Schema({
children: [childSchema]
})
</code></pre><p>Sub-documents enjoy all the same features as normal <a href="./api.html#document-js">documents</a>. The only difference is that they are not saved individually, they are saved whenever their top-level parent document is saved.</p><pre><code class="javascript"><span class="keyword">var</span> Parent = db.model(<span class="string">'Parent'</span>, parentSchema);
<span class="keyword">var</span> parent = <span class="keyword">new</span> Parent({ children: [{ name: <span class="string">'Matt'</span> }, { name: <span class="string">'Sarah'</span> }] })
parent.children[<span class="number">0</span>].name = <span class="string">'Matthew'</span>;
parent.save(callback);
</code></pre><p>If an error occurs in a sub-documents' middleware, it is bubbled up to the <code>save()</code> callback of the parent, so error handling is a snap!</p><pre><code class="javascript">childSchema.pre(<span class="string">'save'</span>, <span class="function"><span class="keyword">function</span> <span class="params">(next)</span> {</span>
<span class="keyword">if</span> (<span class="string">'invalid'</span> == <span class="keyword">this</span>.name) <span class="keyword">return</span> next(<span class="keyword">new</span> Error(<span class="string">'#sadpanda'</span>));
next();
});
<span class="keyword">var</span> parent = <span class="keyword">new</span> Parent({ children: [{ name: <span class="string">'invalid'</span> }] });
parent.save(<span class="function"><span class="keyword">function</span> <span class="params">(err)</span> {</span>
console.log(err.message) <span class="comment">// #sadpanda</span>
})
</code></pre><h3>Finding a sub-document</h3><p>Each document has an <code>_id</code>. DocumentArrays have a special <a href="./api.html#types_documentarray_MongooseDocumentArray-id">id</a> method for looking up a document by its <code>_id</code>.</p><pre><code class="javascript"><span class="keyword">var</span> doc = parent.children.id(id);
</code></pre><h3>Adding sub-docs</h3><p>MongooseArray methods such as <a href="./api.html#types_array_MongooseArray-push">push</a>, <a href="./api.html#types_array_MongooseArray-unshift">unshift</a>, <a href="./api.html#types_array_MongooseArray-addToSet">addToSet</a>, and others cast arguments to their proper types transparently:</p><pre><code class="javascript"><span class="keyword">var</span> Parent = db.model(<span class="string">'Parent'</span>);
<span class="keyword">var</span> parent = <span class="keyword">new</span> Parent;
<span class="comment">// create a comment</span>
post.children.push({ name: <span class="string">'Liesl'</span> });
<span class="keyword">var</span> doc = post.children[<span class="number">0</span>];
console.log(doc) <span class="comment">// { _id: '501d86090d371bab2c0341c5', name: 'Liesl' }</span>
doc.isNew; <span class="comment">// true</span>
post.save(<span class="function"><span class="keyword">function</span> <span class="params">(err)</span> {</span>
<span class="keyword">if</span> (err) <span class="keyword">return</span> handleError(err)
console.log(<span class="string">'Success!'</span>);
});</code></pre><p>Sub-docs may also be created without adding them to the array by using the <a href="./api.html#types_documentarray_MongooseDocumentArray-create">create</a> method of MongooseArrays.</p><pre><code class="javascript"><span class="keyword">var</span> newdoc = post.children.create({ name: <span class="string">'Aaron'</span> });
</code></pre><h3>Removing docs</h3><p>Each sub-document has it's own <a href="./api.html#types_embedded_EmbeddedDocument-remove">remove</a> method.</p><pre><code class="javascript"><span class="keyword">var</span> doc = parent.children.id(id).remove();
parent.save(<span class="function"><span class="keyword">function</span> <span class="params">(err)</span> {</span>
<span class="keyword">if</span> (err) <span class="keyword">return</span> handleError(err);
console.log(<span class="string">'the sub-doc was removed'</span>)
});
</code></pre><h4 id="altsyntax">Alternate declaration syntax</h4><p><em>New in v3</em> If you don't need access to the sub-document schema instance, you may also declare sub-docs by simply passing an object literal:</p><pre><code class="javascript"><span class="keyword">var</span> parentSchema = <span class="keyword">new</span> Schema({
children: [{ name: <span class="string">'string'</span> }]
})
</code></pre><h3 id="next">Next Up</h3><p>Now that we've covered <code>Sub-documents</code>, let's take a look at <a href="/docs/queries.html">querying</a>.</p></div></div><script>document.body.className = 'load';</script><script>var _gaq = _gaq || [];
_gaq.push(['_setAccount', 'UA-1122274-9']);
_gaq.push(['_trackPageview']);
(function() {
var ga = document.createElement('script'); ga.type = 'text/javascript'; ga.async = true;
ga.src = ('https:' == document.location.protocol ? 'https://ssl' : 'http://www') + '.google-analytics.com/ga.js';
var s = document.getElementsByTagName('script')[0]; s.parentNode.insertBefore(ga, s);
})();</script></body></html>