I'm new at Mongoose. I have two collections => User and Task.
Each User can have multiple tasks but each Task can have only one User.
UserSchema:
const UserSchema = new Schema({
name: {
type: String, // type of the variable
required: [true, "Please provide a name"], // this variable must be filled
},
tasks: [
{
type: mongoose.Schema.ObjectId,
ref: "Task",
},
],
});
TaskSchema:
const TaskSchema = new Schema({
title: {
type: String, // type of the variable
required: [true, "Please provide a title"], // this variable must be filled
},
user: {
type: mongoose.Schema.ObjectId,
required: true,
ref: "User", // give reference to the user model
},
});
The code below lists all Task data with their Users:
await Task.find().populate("user");
But when I list the User data, the task property comes empty:
await User.find().populate(tasks");
Create Task Body:
{
"title": "Task 1",
"user": "64afb6943c764b68ad9c1f61"
}
My question is when I add the new task, should I also add task id to the user tasks property on the MongoDB? Because I can't read the user's task in this way.
Yes. you should push()
the new task
to user.tasks
array.
const user = await User.findById('64afb6943c764b68ad9c1f61');
const task = new Task({ title: 'Task 1', user });
await task.save();
user.tasks.push(task);
await user.save();
Complete working example:
// @ts-nocheck
import mongoose from 'mongoose';
import util from 'util';
import { config } from '../../config';
mongoose.set('debug', true);
console.log(mongoose.version);
const UserSchema = new mongoose.Schema({
name: String,
tasks: [
{
type: mongoose.Schema.ObjectId,
ref: 'Task',
},
],
});
const User = mongoose.model('User', UserSchema);
const TaskSchema = new mongoose.Schema({
title: String,
user: {
type: mongoose.Schema.ObjectId,
required: true,
ref: 'User',
},
});
const Task = mongoose.model('Task', TaskSchema);
(async function main() {
try {
await mongoose.connect(config.MONGODB_URI);
// seed
const u = new User({ name: 'Nick' });
await u.save();
// create task
const user = await User.findById(u._id);
const task = new Task({ title: 'Task 1', user });
await task.save();
user.tasks.push(task);
await user.save();
// populate
const users = await User.find().populate('tasks');
console.log('users:', util.inspect(users, false, null));
const tasks = await Task.find().populate('user');
console.log('tasks: ', util.inspect(tasks, false, null));
} catch (error) {
console.error(error);
} finally {
await mongoose.connection.close();
}
})();
Logs:
users: [
{
_id: new ObjectId("64afbe6276adf1531b71117c"),
name: 'Nick',
tasks: [
{
_id: new ObjectId("64afbe6376adf1531b71117f"),
title: 'Task 1',
user: new ObjectId("64afbe6276adf1531b71117c"),
__v: 0
}
],
__v: 1
}
]
Mongoose: tasks.find({}, {})
Mongoose: users.find({ _id: { '$in': [ ObjectId("64afbe6276adf1531b71117c") ], [Symbol(mongoose#trustedSymbol)]: true }}, { skip: undefined, limit: undefined, perDocumentLimit: undefined })
tasks: [
{
_id: new ObjectId("64afbe6376adf1531b71117f"),
title: 'Task 1',
user: {
_id: new ObjectId("64afbe6276adf1531b71117c"),
name: 'Nick',
tasks: [ new ObjectId("64afbe6376adf1531b71117f") ],
__v: 1
},
__v: 0
}
]