Mongoose子文档同时满足多个条件

时间:2013-08-08 14:25:35

标签: node.js mongodb mongoose

我的架构设置为ResourceSkillResourceSkillLevel。前两个基本上只是名称,后者有资源,技能和级别的参考。我想同时选择与某些技能水平匹配的所有Resource


模式

// Omitting fields that don't matter for the purpose of the question
ResourceSchema = new Schema({name: String});
SkillSchema = new Schema({name: String});
ResourceSkillLevelSchema = new Schema({                                         
    "resource": {type: Schema.ObjectId, ref: "Resource"},                       
    "skill": {type: Schema.ObjectId, ref: "Skill"},                             
    "level": {type: Number, min: 1, max: 5}                                     
});

问题

目前我有:

ResourceSkillLevel.find({$and: [
    {skill: "node.js", level: {$gte: 3}},
    {skill: "mongodb", level: {$gte: 3}},
]})

这会返回ResourceSkillLevel条目,但有两个问题:

  • 这种情况是不可能的,因为一个ResourceSkillLevel条目不能同时满足这两个条件
  • 我想获得满足所有这些条件的Resource条目。如果我收到ResourceSkillLevel条目,我可以从中获取Resource,但我确信有更简单的方法。

要求

如果您不理解,我需要的是一种同时获取与所需Resource个条目匹配的所有ResourceSkillLevel个条目的方法。也就是说,基于上面的查询,我应该能够得到一个Resource,其中包含node.js mongodb中的4个,但是获得的资源是在node.js中只有2个或根本没有任何技能的技能等级。

1 个答案:

答案 0 :(得分:1)

我实现这个的方法是更改​​模式如下:

SkillSchema = new Schema({name: String, level: {type: Number, min: 1, max: 5}});
ResourceSchema = new Schema({name: String, Skills: [SkillSchema]});

我忘了如果mongoose允许嵌入这样的模式......

然后你可以像这样进行查询:

Resource.find({skills: [{"name": "nodejs", "level": 2},{"name": "mongodb", "level": 3}]})

这应该可以帮助你做到最好。


编辑以显示更好的方法。

您可以将技能存储在他们自己的集合中,然后只在资源架构中存储一系列技能,但包含以下字段:

SkillSchema = new Schema({name: String });
ResourceSchema = new Schema({name: String, Skills: [{skill_id: String, level: {type: Number, min: 1, max: 5}}]});

通过这种方式,您可以拥有单一的技能集合,然后在资源上的技能集合中引用技能的_id。

您的查询如下:

Resource.find({skills: [{"skill_id": skill id from SkillSchema collection, "level": 2},{"skill_id": skill id from SkillSchema collection, "level": 3}]})

这应该对你有用