Databases · 06/09 5 min1 hands-on
Relations and populate
Store an id, not a copy. Then let populate fill in the related document when you read.
A post has an author. Don't copy the author's name into every post (it goes stale when they rename). Store a reference: the author's _id.
const postSchema = new mongoose.Schema({
title: String,
author: { type: mongoose.Schema.Types.ObjectId, ref: "User" }, // ref names the model
});
Reading it back
const post = await Post.findOne();
post.author; // ObjectId("66f…"): just the id
const full = await Post.findOne().populate("author");
full.author.name; // "Ada": the whole user document
populate runs a second lookup for you and swaps the id for the document.
Filtering by a reference
Post.find({ author: userId }); // all posts by this user
Comparing ids
post.author is an ObjectId object, not a string. post.author === req.user.id is always false. Use post.author.equals(id) or compare strings: String(post.author) === String(id).
Embed or reference?
- Embed small things that belong to one parent and are read together (an order's line items).
- Reference things that are shared or grow without limit (users, comments on a popular post).
Your turn · 1 exercise0/1 solved
Posts and their authors
Posts reference users. postsWithAuthors() returns every post with its author filled in (sorted by title), and postsBy(userId) returns one user's posts.
Loading editor…
Next in Databases
Pagination that adds up