Skip to content

docs: rewrite documents docs - #16298

Merged
vkarpov15 merged 22 commits into
masterfrom
vkarpov15/new-documents-docs
Jun 4, 2026
Merged

docs: rewrite documents docs#16298
vkarpov15 merged 22 commits into
masterfrom
vkarpov15/new-documents-docs

Conversation

@vkarpov15

Copy link
Copy Markdown
Collaborator

Summary

I've always felt like our existing Documents guide is one of the weakest pages on the documentation, so I went ahead and rewrote it. I tried to highlight some more common pain points and points of confusion:

  1. Mongoose documents are not POJOs - what is a hydrated document?
  2. Cast errors being stored internally - cast errors don't surface until validation
  3. More info on how save() works especially with change tracking
  4. More guidance on middleware, especially with regards to updateOne() etc. not triggering save() middleware

Examples

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This PR rewrites the Mongoose “Documents” guide to better explain common confusion points around hydrated vs lean documents, casting vs validation, save() change tracking, and middleware behavior. It also includes a small documentation example update for Schema.Types.Date.checkRequired() and a minor formatting tweak in the docs “copy code” script.

Changes:

  • Rewrote docs/documents.md with expanded explanations and new examples for hydration, save(), casting/validation, required behavior, and middleware.
  • Updated the SchemaDate.checkRequired() JSDoc example to focus on disallowing invalid dates.
  • Adjusted an async arrow style in docs/js/copy-code.js.

Reviewed changes

Copilot reviewed 2 out of 3 changed files in this pull request and generated 6 comments.

File Description
lib/schema/date.js Updates the Date schematype checkRequired() documentation example.
docs/js/copy-code.js Minor formatting tweak to the async arrow function used for copy-to-clipboard.
docs/documents.md Major rewrite of the Documents guide with new structure and examples.

Comment thread docs/documents.md Outdated
Comment thread docs/documents.md Outdated
Comment thread docs/documents.md Outdated
Comment thread docs/documents.md Outdated
Comment thread docs/documents.md Outdated
Comment thread docs/documents.md Outdated
vkarpov15 and others added 5 commits May 26, 2026 15:38
Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com>
Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com>
Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com>
Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com>
@hasezoey hasezoey added the docs This issue is due to a mistake or omission in the mongoosejs.com documentation label May 27, 2026
Comment thread docs/documents.md Outdated
Comment thread docs/documents.md
Comment thread docs/documents.md Outdated
@vkarpov15 vkarpov15 modified the milestones: 9.6.3, 9.7 May 27, 2026

@AbdelrahmanHafez AbdelrahmanHafez left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Dumping my thought process as I try to read this from a fresh reader's perspective:


Mongoose documents are JavaScript objects backed by MongoDB data

I'm worried this could be misinterpreted as POJOs (the actual POJOs with the data in the mongo server). The next sentence and the Hydrated Documents vs Lean Documents section clarify it, but I think it's worth avoiding the misunderstanding in the first place. I'd change JavaScript objects to Document class instances. They're technically the same thing, but one can be mistaken for POJOs.


They are instances of Mongoose's Document class

...later, in "What is a Document":

A Mongoose document is an instance of a Model. When you instantiate a model, you create a new document.

This is a bit confusing on first read: are they instances of a Document or a Model? How do Model and Document relate?

Do we assume the reader of this page has already read the Models doc, or should this page stand on its own without having to go somewhere else to understand the relationship?


You can use the lean() method to make Mongoose queries return POJOs instead of hydrated documents.

Would be nice to briefly explain when I'd reach for lean() over hydrated docs, the performance benefit for read-only cases, and the drawbacks. If it's covered in detail elsewhere we can link to it, or just re-explain here.


Nitpick on the Setting Nested Properties code example:

const schema = new Schema({
  nested: {
    subdoc: new Schema({
      name: String
    })
  }
});
const TestModel = mongoose.model('Test', schema);

const doc = new TestModel();
doc.set('nested.subdoc.name', 'John Smith');
doc.nested.subdoc.name; // 'John Smith'

A newcomer might think subdoc and nested have meaningful distinction rather than just being generic path names. I'd rewrite this with a realistic example. More generally: using different realistic examples across the file helps people who learn by pattern recognition see what's constant and what's variable.


On this snippet, we tell readers not to use nullish coalescing assignments without explaining why it works in the first case but not the second:

// The following works fine
const doc3 = new TestModel();
doc3.nested.subdoc ??= {};
doc3.nested.subdoc.name = 'John Smythe';

// The following does **NOT** work.
// Do not use the following pattern with Mongoose documents.
const doc4 = new TestModel();
(doc4.nested.subdoc ??= {}).name = 'Charlie Smith';
doc4.nested.subdoc; // Empty object
doc4.nested.subdoc.name; // undefined.

I honestly haven't seen this pattern used in the wild. We should either explain more (why it works in the first case, why not in the second, ideally the root cause), or drop it entirely given how rare it is. I'm leaning towards keeping it but explaining more.


Very nitpicky: the save() lifecycle being an image looks a bit off, especially on the dark theme. Probably fine for now, but might be worth figuring out how to inject custom HTML into the docs later if we don't have an easy way to do it.

Comment thread docs/documents.md
Comment thread docs/documents.md Outdated
@hasezoey

Copy link
Copy Markdown
Collaborator

Very nitpicky: the save() lifecycle being an image looks a bit off, especially on the dark theme. Probably fine for now, but might be worth figuring out how to inject custom HTML into the docs later if we don't have an easy way to do it.

Maybe we could consider switching the image to use Mermaid? (it is natively supported in github comments and github markdown display, though we would likely need another dependency for the website OR statically generate the html once)

@vkarpov15

Copy link
Copy Markdown
Collaborator Author

"A newcomer might think subdoc and nested have meaningful distinction rather than just being generic path names." <-- they do have a meaningful distinction, but just not in this context, so you're right to call that out as a red herring.

@AbdelrahmanHafez

Copy link
Copy Markdown
Collaborator

Maybe we could consider switching the image to use Mermaid? (it is natively supported in github comments and github markdown display, though we would likely need another dependency for the website OR statically generate the html once)

My preference here would be some native HTML, gives us a lot more control over the styling, but Mermaid also works.
For the sake of experimenting, here's how Mermaid diagram would look like:

---
title: "save() Lifecycle"
---
flowchart TB
A("`**🛡️ 1. Pre-Validate Middleware**
Runs pre('validate') middleware.
Use this to prepare or modify the document before validation.`")
B("`**🔍 2. Validate**
Mongoose casts values and runs built-in validators and custom validators.
_If validation fails, save() is aborted and no changes are written._`")
C("`**✅ 3. Post-Validate Middleware**
Runs post('validate') middleware.
Runs whether validation succeeds or fails.
Use this for logging, metrics, etc.`")
D("`**⚙️ 4. Pre-Save Middleware**
Runs pre('save') middleware.
Use this for tasks that should run right before the document is persisted (e.g. hashing a password, setting timestamps).`")
E[("`**🗄️ 5. Write to MongoDB**
Mongoose generates the appropriate write operation:
• New document: insertOne()
• Existing document: updateOne() with only the modified paths`")]
F("`**📥 6. Post-Save Middleware**
Runs post('save') middleware.
Runs after the write attempt.
The document is now up to date with what's in MongoDB.`")

A --> B --> C --> D --> E --> F

classDef purple fill:#EDE7F6,stroke:#7E57C2,stroke-width:2px,color:#311B92;
classDef green fill:#E8F5E9,stroke:#43A047,stroke-width:2px,color:#1B5E20;
classDef orange fill:#FFF3E0,stroke:#FB8C00,stroke-width:2px,color:#E65100;
classDef blue fill:#E3F2FD,stroke:#1E88E5,stroke-width:2px,color:#0D47A1;

class A,C,F purple;
class B green;
class D orange;
class E blue;
Loading

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Copilot reviewed 2 out of 2 changed files in this pull request and generated 3 comments.

Comment thread lib/schema/date.js
Comment thread docs/documents.md Outdated
Comment thread docs/documents.md Outdated
@vkarpov15

vkarpov15 commented May 29, 2026

Copy link
Copy Markdown
Collaborator Author

@AbdelrahmanHafez how do you like this dark theme image?

image

vkarpov15 and others added 3 commits May 29, 2026 13:15
Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com>
@vkarpov15
vkarpov15 requested a review from IslandRhythms May 29, 2026 17:26

@IslandRhythms IslandRhythms left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Left a couple comments but LGTM otherwise

Comment thread docs/documents.md Outdated
Comment thread docs/documents.md Outdated
@vkarpov15
vkarpov15 merged commit 350e64b into master Jun 4, 2026
28 checks passed
@hasezoey
hasezoey deleted the vkarpov15/new-documents-docs branch June 4, 2026 17:39
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

docs This issue is due to a mistake or omission in the mongoosejs.com documentation

Projects

None yet

Development

Successfully merging this pull request may close these issues.

5 participants