<!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.6.0: Documents</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/purecss@1.0.0/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"><link rel="stylesheet" href="/docs/css/inlinecpc.css"><script type="text/javascript" src="/docs/js/native.js"></script></head><body><div id="layout"><div id="mobile-menu"><a class="menu-link" id="menuLink" href="#menu"><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 class="pure-menu-heading" id="logo-container"><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" id="navbar"><li class="pure-menu-horizontal pure-menu-item pure-menu-has-children pure-menu-allow-hover version"><a class="pure-menu-link" href="#">Version 5.6.0</a><ul class="pure-menu-children"><li class="pure-menu-item"><a class="pure-menu-link" href="/docs/4.x">Version 4.13.18</a></li><li class="pure-menu-item"><a class="pure-menu-link" href="/docs/3.8.x">Version 3.8.40</a></li></ul></li><li class="pure-menu-item search"><input id="search-input-nav" type="text" placeholder="Search"><button id="search-button-nav"><img src="/docs/images/search.svg"></button></li><li class="pure-menu-item"><a class="pure-menu-link" href="/docs/index.html">Quick Start</a></li><li class="pure-menu-item"><a class="pure-menu-link" href="/docs/guides.html">Guides</a></li><li class="pure-menu-item sub-item"><a class="pure-menu-link" href="/docs/guide.html">Schemas</a></li><li class="pure-menu-item sub-item"><a class="pure-menu-link" href="/docs/schematypes.html">SchemaTypes</a></li><li class="pure-menu-item sub-item"><a class="pure-menu-link" href="/docs/connections.html">Connections</a></li><li class="pure-menu-item sub-item"><a class="pure-menu-link" href="/docs/models.html">Models</a></li><li class="pure-menu-item sub-item"><a class="pure-menu-link" href="/docs/documents.html">Documents</a></li><li class="pure-menu-item sub-item"><a class="pure-menu-link" href="/docs/subdocs.html">Subdocuments</a></li><li class="pure-menu-item sub-item"><a class="pure-menu-link" href="/docs/queries.html">Queries</a></li><li class="pure-menu-item sub-item"><a class="pure-menu-link" href="/docs/validation.html">Validation</a></li><li class="pure-menu-item sub-item"><a class="pure-menu-link" href="/docs/middleware.html">Middleware</a></li><li class="pure-menu-item sub-item"><a class="pure-menu-link" href="/docs/populate.html">Populate</a></li><li class="pure-menu-item sub-item"><a class="pure-menu-link" href="/docs/discriminators.html">Discriminators</a></li><li class="pure-menu-item sub-item"><a class="pure-menu-link" href="/docs/plugins.html">Plugins</a></li><li class="pure-menu-item"><a class="pure-menu-link" href="/docs/api.html">API</a></li><li class="pure-menu-item sub-item"><a class="pure-menu-link" href="/docs/api/mongoose.html">Mongoose</a></li><li class="pure-menu-item sub-item"><a class="pure-menu-link" href="/docs/api/schema.html">Schema</a></li><li class="pure-menu-item sub-item"><a class="pure-menu-link" href="/docs/api/connection.html">Connection</a></li><li class="pure-menu-item sub-item"><a class="pure-menu-link" href="/docs/api/document.html">Document</a></li><li class="pure-menu-item sub-item"><a class="pure-menu-link" href="/docs/api/model.html">Model</a></li><li class="pure-menu-item sub-item"><a class="pure-menu-link" href="/docs/api/query.html">Query</a></li><li class="pure-menu-item sub-item"><a class="pure-menu-link" href="/docs/api/aggregate.html">Aggregate</a></li><li class="pure-menu-item sub-item"><a class="pure-menu-link" href="/docs/api/schematype.html">SchemaType</a></li><li class="pure-menu-item sub-item"><a class="pure-menu-link" href="/docs/api/virtualtype.html">VirtualType</a></li><li class="pure-menu-item"><a class="pure-menu-link" href="/docs/compatibility.html">Version Compatibility</a></li><li class="pure-menu-item"><a class="pure-menu-link" href="/docs/faq.html">FAQ</a></li><li class="pure-menu-item"><a class="pure-menu-link" href="/docs/further_reading.html">Further Reading</a></li></ul><div class="cpc-ad"><script async type="text/javascript" src="//cdn.carbonads.com/carbon.js?zoneid=1673&serve=C6AILKT&placement=mongoosejscom" id="_carbonads_js"></script></div></div></div><div class="container"><div id="content"><h2 id="documents">Documents</h2>
<script>
  _native.init("CK7DT53U",{
    targetClass: 'native-inline'
  });
</script>

<div class="native-inline">
  <a href="#native_link#"><span class="sponsor">Sponsor</span> #native_company# — #native_desc#</a>
</div>

<p>Mongoose <a href="./api.html#document-js">documents</a> represent a one-to-one mapping
to documents as stored in MongoDB. Each document is an instance of its
<a href="./models.html">Model</a>.</p>
<ul class="toc">
  <li><a href="#documents-vs-models">Documents vs Models</a></li>
  <li><a href="#retrieving">Retrieving</a></li>
  <li><a href="#updating">Updating</a></li>
  <li><a href="#validating">Validating</a></li>
  <li><a href="#overwriting">Overwriting</a></li>
</ul>

<h3 id="documents-vs-models">Documents vs Models</h3>
<p><a href="api.html#Document">Document</a> and <a href="api.html#Model">Model</a> are distinct
classes in Mongoose. The Model class is a subclass of the Document class.
When you use the <a href="api.html#Model">Model constructor</a>, you create a
new document.</p>
<pre><code class="language-javascript"><span class="hljs-keyword">const</span> MyModel = mongoose.model(<span class="hljs-string">'Test'</span>, <span class="hljs-keyword">new</span> Schema({ name: <span class="hljs-built_in">String</span> }));
<span class="hljs-keyword">const</span> doc = <span class="hljs-keyword">new</span> MyModel();

doc <span class="hljs-keyword">instanceof</span> MyModel; <span class="hljs-comment">// true</span>
doc <span class="hljs-keyword">instanceof</span> mongoose.Model; <span class="hljs-comment">// true</span>
doc <span class="hljs-keyword">instanceof</span> mongoose.Document; <span class="hljs-comment">// true</span></code></pre>
<p>In Mongoose, a &quot;document&quot; generally means an instance of a model.
You should not have to create an instance of the Document class without
going through a model.</p>
<h3 id="retrieving">Retrieving</h3>
<p>When you load documents from MongoDB using model functions like <a href="api.html#model_Model.findOne"><code>findOne()</code></a>,
you get a Mongoose document back.</p>
<pre><code class="language-javascript"><span class="hljs-keyword">const</span> doc = <span class="hljs-keyword">await</span> MyModel.findOne();

doc <span class="hljs-keyword">instanceof</span> MyModel; <span class="hljs-comment">// true</span>
doc <span class="hljs-keyword">instanceof</span> mongoose.Model; <span class="hljs-comment">// true</span>
doc <span class="hljs-keyword">instanceof</span> mongoose.Document; <span class="hljs-comment">// true</span></code></pre>
<h3 id="updating">Updating</h3>
<p>Mongoose documents track changes. You can modify a document using vanilla
JavaScript assignments and Mongoose will convert it into <a href="https://docs.mongodb.com/manual/reference/operator/update/">MongoDB update operators</a>.</p>
<pre><code class="language-javascript">doc.name = <span class="hljs-string">'foo'</span>;

<span class="hljs-comment">// Mongoose sends a `updateOne({ _id: doc._id }, { $set: { name: 'foo' } })`</span>
<span class="hljs-comment">// to MongoDB.</span>
<span class="hljs-keyword">await</span> doc.save();</code></pre>
<p>If the document with the corresponding <code>_id</code> is not found, Mongoose will
report a <code>DocumentNotFoundError</code>:</p>
<pre><code class="language-javascript"><span class="hljs-keyword">const</span> doc = <span class="hljs-keyword">await</span> MyModel.findOne();

<span class="hljs-comment">// Delete the document so Mongoose won't be able to save changes</span>
<span class="hljs-keyword">await</span> MyModel.deleteOne({ _id: doc._id });

doc.name = <span class="hljs-string">'foo'</span>;
<span class="hljs-keyword">await</span> doc.save(); <span class="hljs-comment">// Throws DocumentNotFoundError</span></code></pre>
<p>The <a href="api.html#model_Model-save"><code>save()</code></a> function is generally the right
way to update a document with Mongoose. With <code>save()</code>, you get full
<a href="validation.html">validation</a> and <a href="middleware.html">middleware</a>.</p>
<p>For cases when <code>save()</code> isn&#39;t flexible enough, Mongoose lets you create
your own <a href="https://docs.mongodb.com/manual/reference/operator/update/">MongoDB updates</a>
with casting, <a href="middleware.html#notes">middleware</a>, and <a href="validation.html#update-validators">limited validation</a>.</p>
<pre><code class="language-javascript"><span class="hljs-comment">// Update all documents in the `mymodels` collection</span>
<span class="hljs-keyword">await</span> MyModel.updateMany({}, { $set: { name: <span class="hljs-string">'foo'</span> } });</code></pre>
<p><em>Note that <code>update()</code>, <code>updateMany()</code>, <code>findOneAndUpdate()</code>, etc. do <em>not</em>
execute <code>save()</code> middleware. If you need save middleware and full validation,
first query for the document and then <code>save()</code> it.</em></p>
<h3 id="validating">Validating</h3>
<p>Documents are casted validated before they are saved. Mongoose first casts
values to the specified type and then validates them. Internally, Mongoose
calls the document&#39;s <a href="api.html#document_Document-validate"><code>validate()</code> method</a>
before saving.</p>
<pre><code class="language-javascript"><span class="hljs-keyword">const</span> schema = <span class="hljs-keyword">new</span> Schema({ name: <span class="hljs-built_in">String</span>, age: { type: <span class="hljs-built_in">Number</span>, min: <span class="hljs-number">0</span> } });
<span class="hljs-keyword">const</span> Person = mongoose.model(<span class="hljs-string">'Person'</span>, schema);

<span class="hljs-keyword">let</span> p = <span class="hljs-keyword">new</span> Person({ name: <span class="hljs-string">'foo'</span>, age: <span class="hljs-string">'bar'</span> });
<span class="hljs-comment">// Cast to Number failed for value "bar" at path "age"</span>
<span class="hljs-keyword">await</span> p.validate();

<span class="hljs-keyword">let</span> p2 = <span class="hljs-keyword">new</span> Person({ name: <span class="hljs-string">'foo'</span>, age: <span class="hljs-number">-1</span> });
<span class="hljs-comment">// Path `age` (-1) is less than minimum allowed value (0).</span>
<span class="hljs-keyword">await</span> p2.validate();</code></pre>
<p>Mongoose also supports limited validation on updates using the <a href="validation.html#update-validators"><code>runValidators</code> option</a>.
Mongoose casts parameters to query functions like <code>findOne()</code>, <code>updateOne()</code>
by default. However, Mongoose does <em>not</em> run validation on query function
parameters by default. You need to set <code>runValidators: true</code> for Mongoose
to validate.</p>
<pre><code class="language-javascript"><span class="hljs-comment">// Cast to number failed for value "bar" at path "age"</span>
<span class="hljs-keyword">await</span> Person.updateOne({}, { age: <span class="hljs-string">'bar'</span> });

<span class="hljs-comment">// Path `age` (-1) is less than minimum allowed value (0).</span>
<span class="hljs-keyword">await</span> Person.updateOne({}, { age: <span class="hljs-number">-1</span> }, { runValidators: <span class="hljs-literal">true</span> });</code></pre>
<p>Read the <a href="./validation.html">validation</a> guide for more details.</p>
<h3 id="next-up">Next Up</h3>
<p>Now that we&#39;ve covered Documents, let&#39;s take a look at
<a href="/docs/subdocs.html">Subdocuments</a>.</p>
</div></div><script type="text/javascript">var xhr = new XMLHttpRequest();
xhr.open('POST', 'https://g0a3nbw0xa.execute-api.us-east-1.amazonaws.com/prod/track', true);
xhr.setRequestHeader('Content-Type', 'application/json');
xhr.onreadystatechange = function() {};
xhr.send(JSON.stringify({
  path: window.location.pathname,
  hostname: window.location.hostname,
  hash: window.location.hash
}));</script><script type="text/javascript" src="/docs/js/navbar-search.js"></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>