使用嵌套字段在MongoDB / Mogoose中创建多对多关系?

时间:2018-03-06 06:14:39

标签: mongodb mongoose mongodb-query

我目前正试图在mongodb / mongoose中创建一个多对多的关系。

我有两个模式:

// User Schema
var UserSchema = mongoose.Schema({
    email: {
        type: String,
        index:true
    },
    name: {
        type: String
    },
    tasks:[{type:mongoose.Schema.ObjectId, ref: 'Tasks'}]
});

// Tasks Schema
var TaskSchema = mongoose.Schema({
    name: {
        type: String,
        index: true
    },
    description: {
        type: String
    },
    status:{
        type: String
    },
});

这里的想法是,每个用户都可以承担任务,任务将拥有每个用户自己的状态(例如,未启动,进入,完成,失败)。当用户进行任务时,此状态将发生变化。每个用户都会看到相同的任务(即名称+描述),但会有不同的状态。此外,每个任务都有自己的状态(可用,隐藏),这将指示用户是否可以看到任务。这对每个用户来说都不是唯一的。

到目前为止,这是我的思考过程:

我认为我可以将每个任务的objectIds与用户一起嵌套在一起。例如:

{
   email: "Bob@bob.com"
   name: "Bob",
   tasks: {
     { _id: 001, status: "Active"},
     {_id: 002, status: "inProgress"},
     { _id: 003, status: "Failed"}
   }
 },
 {
   email: "Mary@mary.com"
   name: "Mary",
   tasks: {
     { _id: 001, status: "Failed"},
     { _id: 002, status: "Active"},
     { _id: 003, status: "Active"}
   }
 }

但是,这意味着无论何时创建新任务,我都需要将其添加到所有用户的任务列表中,状态设置为默认值(例如notStarted)。此外,每当我添加新用户时,我都需要所有任务并将其添加到用户的任务列表中。

这对我来说似乎有些笨拙,我觉得必须有更好的方法。如果这个最好的方法,我不太清楚我会用它来写这个。我想也许可以使用addFieldsPush更合适?或者这会创建arrays that grow without bound?这可能不是最好的主意,因为它是我读过的Mongo反模式?

我还发现this post有点相关,但它是从大约6年前开始的,我认为我需要更多深度或代码示例。

任何帮助将不胜感激!

1 个答案:

答案 0 :(得分:1)

如果要在创建新任务时在用户中添加新任务,则查询应为:

  taskCtr.create = (req, res) => {
  const {
      name,
      description,
      status
  } = req.body;

  TaskSchema.create({
      name,
      description,
      status
  }).then((result) => {
      if (result) {
          UserSchema.update({}, {
              $push: {
                  tasks: {
                      _id: result._id,
                      status: result.status
                  }
              }
          }, {
              multi: true
          }).then((userUpdated) => {
              res.status(200).json({
                  message: 'A new Task created successfully!'
              })
          }).catch((err) => {
              res.status(500).json({
                  error: 'Internal server error!'
              });
          });
      }
  }).catch((err) => {
      res.status(500).json({
          error: 'Internal server error!'
      });
  });
 };