【问题标题】:MongoDB complex associationsMongoDB 复杂关联
【发布时间】:2023-03-24 17:48:01
【问题描述】:

我正在尝试弄清楚如何构建我的猫鼬模型。我有一个用户模型、一个任务模型和一个项目模型。项目将有用户,每个用户都有针对该特定项目的任务。我进行此设置的方式是 User 模型具有对 Project 模型的架构引用,而 Task 模型具有对用户的架构引用。我怎样才能做到这一点,以便在我呈现检索到的信息时,每个项目都将显示其相关成员,并且每个成员都将拥有针对该特定项目的相关任务。我还有一个用户模型的管理属性,它只是一个布尔值,默认设置为 false。这样做的目的是,当用户创建团队时,Admin 属性将设置为 True,从而允许管理员为管理员创建的项目中的用户设置任务。问题是,在用户创建团队后,如果管理员设置为 true,我的前端的三元条件将显示基于“管理员”属性的布尔值的表单输入对于所有项目,即使是用户不是管理员的项目。

我正在使用 React 进行渲染。

//任务模型

var mongoose = require('mongoose');
var Schema = mongoose.Schema;

var TodoSchema = new Schema({
  task: {
    type: String
  },
  userTasks: [{
    type: Schema.Types.ObjectId,
    ref: "User"
  }]
});

var Task = mongoose.model('Task', TodoSchema);

module.exports = Task;

//用户模型

var mongoose = require("mongoose");

var Schema = mongoose.Schema;

var UserSchema = new Schema({
  name: {
    type: String,
    trim: true,
    required: "First Name is Required"
  },
  username: {
    type: String,
    trim: true,
    required: "Username is Required"
  },
  skills: {
    type: String,
    trim : true
  },
  avatar: {
    type: String
  },
  SQLid: {
    type: Number
  },
  userCreated: {
    type: Date,
    default: Date.now
  },
  lastUpdated: { 
    type: Date
  },
  userAdmin: {
    default: false
  },
  adminTeams: [{
    type: Schema.Types.ObjectId,
    ref: "Team"
  }],
  team: [{
    type: Schema.Types.ObjectId,
    ref: "Team"
  }],
  task: [{
    type: Schema.Types.ObjectId,
    ref: "Task"
  }]
});

var User = mongoose.model("User", UserSchema);

// Export the model so the server can use it
module.exports = User;

//项目模型

var mongoose = require('mongoose');
var Schema = mongoose.Schema;

var TeamSchema = new Schema({


   teamname: {
        type: String,
        trim: true,
        required: "Team Name is Required"
    },
   description: {
      type: String
   },
   tech: {
      type: String
   },
    teamMembers: [{
        type: Schema.Types.ObjectId,
        ref: "User"
    }]


});

var Team = mongoose.model('Team', TeamSchema);

module.exports = Team;

一旦用户创建团队/项目,他们就会成为该创建团队的管理员。管理员有权将任务分配给用户,用户可以属于多个团队。我正在考虑将管理员布尔值移至 Projects/Team 模型,并在创建团队后将该属性赋予用户的 _id,然后我将使用这些作为键来匹配并使用三元组来呈现表单(如果他们是项目)观看是他们创造的。但是,我仍然对如何将每个用户与任务相关联感到困惑,并且用户可以属于多个团队,因此我需要用户必须在正确的项目/团队部分中的任务。

我在说什么

//项目页面(下面的 div 只是项目页面上列出的众多项目中的一个)

<div>
Project/Team 1

  User Name -> User Task
  User Name -> User Task
  User Name -> User Task
  ...
</div>

<div>
Project/Team 2

  User Name -> User Task
  User Name -> User Task
  User Name -> User Task
  ...
</div>

【问题讨论】:

    标签: node.js mongodb mongoose


    【解决方案1】:

    一般来说,您应该查看 associations 上的 mongodb 文档

    当您处理 mongodb 时,您可能希望查看在您的文档中保存更多相关信息,而不是在 sql 环境中。有一个很好的顶级答案here 关于设计您的数据以很好地使用 mongodb。

    您的管理问题听起来像是一个无法通过您的数据库解决的编码问题。如果您的表单显示在布尔字段上,我很难理解为什么您的表单需要一个三元组,但无法提供任何进一步的帮助:

    if (user.admin) {//form}
    

    没有 sn-ps 或有关您的前端架构或相关三元组的信息。听起来你可能为自己把事情复杂化了。

    编辑您的更新:我会更改您的模型,以便项目存储创建它们的用户。

    var mongoose = require('mongoose');
    var Schema = mongoose.Schema;
    
    var TeamSchema = new Schema({
    
    
       teamname: {
            type: String,
            trim: true,
            required: "Team Name is Required"
        },
       description: {
          type: String
       },
       tech: {
          type: String
       },
        teamMembers: [{
            type: Schema.Types.ObjectId,
            ref: "User"
        }],
       // now holds the 'admin' of the team. you can keep the admin naming 
       //if you like
       creator: [{
            type: Schema.Types.ObjectId,
            ref: "User"
        }]
    
    });
    
    var Team = mongoose.model('Team', TeamSchema);
    
    module.exports = Team;
    

    您的用户模型也可以使用一些命名改进,用户列上的管理字段通常用于像您这样的应用程序管理员,而不是项目中的管理员。

    var mongoose = require("mongoose");
    
    var Schema = mongoose.Schema;
    
    var UserSchema = new Schema({
      name: {
        type: String,
        trim: true,
        required: "First Name is Required"
      },
      username: {
        type: String,
        trim: true,
        required: "Username is Required"
      },
      skills: {
        type: String,
        trim : true
      },
      avatar: {
        type: String
      },
      SQLid: {
        type: Number
      },
      // you might want to look up timestamps createdAt and updatedAt 
      // instead of this field 
      userCreated: {
        type: Date,
        default: Date.now
      },
      lastUpdated: { 
        type: Date
      },
      userAdmin: {
        default: false
      },
      // this could be removed as its is now stored on the Team schema
      adminTeams: [{
        type: Schema.Types.ObjectId,
        ref: "Team"
      }],
      // this should be plural as it represents a one to many 
      teams: [{
        type: Schema.Types.ObjectId,
        ref: "Team"
      }],
       // tasks is removed because you can find them from the Task schema
    });
    
    var User = mongoose.model("User", UserSchema);
    
    // Export the model so the server can use it
    module.exports = User;
    

    由于您的任务模型需要特定于团队,因此可以如下所示:

    var mongoose = require('mongoose');
    var Schema = mongoose.Schema;
    
    var TodoSchema = new Schema({
      task: {
        type: String
      },
      // I would suggest an 'assignedTo', 'owner', or 'taskOwner' naming
      // as user may be a bit non-descriptive.
      user: [{
        type: Schema.Types.ObjectId,
        ref: "User"
      }],
      team: [{
        type: Schema.Types.ObjectId,
        ref: "Team"
      }]
    });
    
    var Task = mongoose.model('Task', TodoSchema);
    
    module.exports = Task;
    

    有很多方法可以通过架构加载您想要的信息,但是经过这种轻微的重组,您可以获得所需的所有信息,如下所示:

        var tasks;
        Team.findOne({'id': the_team_id}, function(err, team) {
          if (err) return handleError(err)
          Task.find({'team': team}).populate('user').exec(function(err, foundTasks) {
              tasks = foundTasks
            })
        })
    

    您现在可以通过执行以下操作来检查您的管理员:

    team.creator.id === user.id 
    

    mogoosepopulate

    【讨论】:

    • 感谢您的回复。我做三元组的原因是因为我使用 react 来渲染 dom 元素,具体取决于用户是否是特定组的管理员。用户在一个项目中,每个项目都有用户。每个用户都有一个任务。我将使用模型架构编辑我的帖子。
    • 如果可以的话,也包括你的反应页面
    • 我更新了我对架构上一些 cmets 的回答,这可能会对您有所帮助,以及如何一次性按团队获取 Teams 用户和任务
    • 好的,包含对用户和团队的引用的任务模型是否会正确地将每个用户与分配给他们的正确任务和正确的项目/团队相关联?因此,当管理员将任务分配给特定用户时,我想我会 findOneAndUpdate 与团队成员 _id 我正在分配任务,然后当它被发现时,$push 团队 _id 到团队模式数组和用户的 _id进入用户架构数组
    • 您可以根据需要针对您希望执行的查询类型调整架构,这里的重要内容是围绕 .populate 函数进行设计。在第一个查询示例中,除非您使用 .populate('user') 调用,否则任务不会有其相关用户,但它们将用于正确的项目/团队。你可以改为 var 任务; Team.findById(the_team_id).exec(function(err, team) { if (err) return handleError(err) Task.find({'team': team}).populate('user').exec( function(err , foundTasks) { tasks = foundTasks }) }).
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-01-31
    • 2021-08-17
    • 2015-11-08
    相关资源
    最近更新 更多