【问题标题】:Mongoose Complex Query by Subdocument子文档的猫鼬复杂查询
【发布时间】:2015-01-13 18:54:21
【问题描述】:

我需要通过OwnerManagerTeam Members 之一找到一个项目。架构如下所示:

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);
}

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

【问题讨论】:

  • 您正在搜索不存在的Product.teams.members。你的意思是要搜索(sudo)or: ["Project.owner", "Project.managers", "Team.members"]
  • Nico 你的teams 属性只是对另一个文档的引用。在进行查询时,mongo 不知道 teams 有一个 members 属性。要进行查询,您需要将teams 创建为嵌入文档。
  • 对不起,我错过了第一句话...在您当前的设置中,您需要通过members: id 查询Team,然后通过or: [{owner: id}, {managers: id}, {teams: teamQueryResponse._id}] 查询Project。跨度>

标签: node.js mongodb mongoose


【解决方案1】:

为了让您的查询正常工作,您可以通过 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 文档和非规范化数据同步。

【讨论】:

  • 谢谢,这正是我所做的(解决方案 1)。我正要发布它作为答案,但你打败了我:)
猜你喜欢
  • 2015-06-26
  • 2017-06-01
  • 2019-10-19
  • 2014-03-21
  • 2013-10-21
  • 2013-04-16
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多