子文档的Mongoose复杂查询

时间:2015-01-06 16:46:30

标签: node.js mongodb mongoose

我需要OwnerManager或其中一个Team Member找到一个项目。这是模式的样子:

var project = new mongoose.Schema({
  title: { type: String, require: true },
  slug: { type: String, require: true },
  description: { type: String, require: true },
  descriptionHtml: { type: String, require: true },
  nextVanityId: { type: Number, default: 1 },
  owner: { type: ObjectId, ref: 'Member', require: true },
  teams: [{ type: ObjectId, ref: 'Team' }],
  managers: [{ type: ObjectId, ref: 'Member' }]
};

var team = new mongoose.Schema({
  name: { type: String, require: true },
  slug: { type: String, require: true },
  project:  { type: ObjectId, require: true, ref: 'Project' },
  created: { type: Date, require: true, default: Date.now },
  members: [{ type: ObjectId, default: null, ref: 'Member' }]
};

我的查询方法如下所示:

function findByMember (member, done) {
  var id = member._id;

  Project
    .find()
    .or([
      { owner: id },
      { managers: id },
      { 'teams.members': id }
    ])
    .exec(done);
}

目前它适用于所有者和管理者,但在查询每个团队的成员集合时我正在绘制空白。我该怎么用?

1 个答案:

答案 0 :(得分:2)

为了使您的查询有效,您可以通过两种方式解决问题。

解决方案1 ​​

让您的团队成为项目中的嵌入式文档:

var team = new mongoose.Schema({
  name: { type: String, require: true },
  slug: { type: String, require: true },
  project:  { type: ObjectId, require: true, ref: 'Project' },
  created: { type: Date, require: true, default: Date.now },
  members: [{ type: ObjectId, default: null, ref: 'Member' }]
};

var project = new mongoose.Schema({
  title: { type: String, require: true },
  slug: { type: String, require: true },
  description: { type: String, require: true },
  descriptionHtml: { type: String, require: true },
  nextVanityId: { type: Number, default: 1 },
  owner: { type: ObjectId, ref: 'Member', require: true },
  teams: [team],
  managers: [{ type: ObjectId, ref: 'Member' }]
};

这样,您的项目文档将包含团队信息,并且teams.members有意义。

解决方案2

将您的Team数据归一化为仅嵌入相关信息:

var team = new mongoose.Schema({
  name: { type: String, require: true },
  slug: { type: String, require: true },
  project:  { type: ObjectId, require: true, ref: 'Project' },
  created: { type: Date, require: true, default: Date.now },
  members: [{ type: ObjectId, default: null, ref: 'Member' }]
};

var project = new mongoose.Schema({
  title: { type: String, require: true },
  slug: { type: String, require: true },
  description: { type: String, require: true },
  descriptionHtml: { type: String, require: true },
  nextVanityId: { type: Number, default: 1 },
  owner: { type: ObjectId, ref: 'Member', require: true },
  teams: [{
    _id: { type: ObjectId, ref: 'Team' },
    members: [{ type: ObjectId, default: null, ref: 'Member' }]
  }],
  managers: [{ type: ObjectId, ref: 'Member' }]
};

在第二种方法中,您需要保持Team文档和非规范化数据同步。