子文档的猫鼬复杂查询
Mongoose Complex Query by Subdocument
我需要通过 Owner
、Manager
或 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
将您的团队作为项目中的嵌入式文档:
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
文档和非规范化数据同步。
我需要通过 Owner
、Manager
或 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
将您的团队作为项目中的嵌入式文档:
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
文档和非规范化数据同步。