MongoDB和Mongoose的一对多关系

huangapple go评论69阅读模式
英文:

MongoDB and Mongoose One-to-many Relationship

问题

我是Mongoose的新手。我有两个集合 => UserTask

每个 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
  }
]

huangapple
  • 本文由 发表于 2023年7月13日 16:50:12
  • 转载请务必保留本文链接:https://go.coder-hub.com/76677538.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定