英文:
MongoDB and Mongoose One-to-many Relationship
问题
我是Mongoose的新手。我有两个集合 => User 和 Task。
每个 User 可以拥有多个任务,但每个 Task 只能属于一个 User。
UserSchema:
const UserSchema = new Schema({
name: {
type: String, // 变量的类型
required: [true, "请提供名称"], // 必须填写此变量
},
tasks: [
{
type: mongoose.Schema.ObjectId,
ref: "Task",
},
],
});
TaskSchema:
const TaskSchema = new Schema({
title: {
type: String, // 变量的类型
required: [true, "请提供标题"], // 必须填写此变量
},
user: {
type: mongoose.Schema.ObjectId,
required: true,
ref: "User", // 引用用户模型
},
});
下面的代码列出了所有 Task 数据及其对应的 User:
await Task.find().populate("user");
但是,当我列出 User 数据时,任务属性为空:
await User.find().populate("tasks");
创建任务请求体:
{
"title": "任务 1",
"user": "64afb6943c764b68ad9c1f61"
}
我的问题是,当我添加新任务时,是否应该将任务ID添加到MongoDB中的用户任务属性中?因为我不能以这种方式读取用户的任务。
英文:
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.
答案1
得分: 1
是的,你应该将新的 task
使用 push()
方法添加到 user.tasks
数组中。
const user = await User.findById('64afb6943c764b68ad9c1f61');
const task = new Task({ title: 'Task 1', user });
await task.save();
user.tasks.push(task);
await user.save();
完整的工作示例:
// @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);
// 种子数据
const u = new User({ name: 'Nick' });
await u.save();
// 创建任务
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();
// 填充数据
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();
}
})();
日志:
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
}
]
英文:
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
}
]
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论