带有嵌套文档的Mongo DB设计

时间:2018-12-28 23:26:16

标签: database mongodb mongoose database-design mongodb-query

我想要有关MongoDB模式设计的最佳实践建议。 我正在创建一个项目经理。我希望用户能够创建任务,并将此任务与项目的某个阶段相关联。 我考虑了两种设计,各有利弊:

第一个设计是:

const ProjectSchema: new Schema ({
  ...
  phases: [{
    phase_id: String,
    name: String,
    status: String,
    startDate: Date,
    endDate: Date,
    tasks: [{
       task_id: String,
       title: String,
       description: String,
       completed: { type: Boolean, default: 'false' },
       ...
    }],
  }]
  ...
});

这里的优点是我每个阶段都有任务,因此如果想要一个阶段的所有任务,查询将花费更少的时间来处理,因为我不必每次都想要某个阶段的任务时都进行过滤。但是,如果需要查询项目的所有任务,则需要获取所有阶段,然后获取进行两次查询的任务。

另一种设计是:

const ProjectScema: new Schema ({
  ...
  phases: [{
    phase_id: String,
    name: String,
    status: String,
    startDate: Date,
    endDate: Date,
    ...
  }],
  tasks: [{
    task_id: String,
    title: String,
    description: String,
    completed: { type: Boolean, default: 'false' },
    phase: { id: mongoose.Types.ObjectId, name: String },
    ...
  }],
  ...
});

在这种情况下,更容易获得项目中分配的所有任务,但是如果我想要一个阶段的所有任务,则必须过滤任务数组。

在两种情况下,如果我都有大量任务,查询可能会很慢。我可以使用更好的设计吗?

另一种解决方案是将任务放在另一个集合中,并在各个阶段中对任务进行引用:

const TaskSchema: new Schema({
    task_id: String
    title: String,
    description: String,
    startDate: Date,
    endDate: Date,
    project_id: String,
    phase_id: String,
    ...
  });

 TaskSchema.index({ task_id: 1 });
 TaskSchema.index({ project_id: 1 });
 const Task = mongoose.model('Task', TaskSchema);

在shcema项目中:

const ProjectScema: new Schema ({
  project_id: String,
  ...
  phases: [{
    phase_id: String,
    name: String,
    status: String,
    startDate: Date,
    endDate: Date,
    tasks: [{
     type: Schema.Types.ObjectId,
     ref: 'Task' 
    }],
    ...
  }]
  ...
});

这样,由于索引,我可以查询项目的所有任务,也可以由于填充而获得阶段的所有任务。 我不知道哪种解决方案最适合使用,因为我会经常读写任务和阶段,并且可能会有大量的阶段和任务(1-2百个)。

0 个答案:

没有答案