Mongo按对象数组过滤文档

时间:2020-05-27 16:01:29

标签: mongodb mongoose

我必须按对象数组过滤候选文档。

在文档中,我具有以下字段:

skills = [
  { _id: 'blablabla', skill: 'Angular', level: 3 },
  { _id: 'blablabla', skill: 'React', level: 2 },
  { _id: 'blablabla', skill: 'Vue', level: 4 },
];

发出请求时,我会获得其他技能,例如:

skills = [
  { skill: 'React', level: 2 },
];

因此,我需要构建一个查询来获取包含该技能以及更高或更高水平的文档。

我尝试执行以下操作:

const conditions = {
  $elemMatch: {
    skill: { $in: skills.map(item => item.skill) },
    level: { $gte: { $in: skills.map(item => item.level) } }
  }
};

Candidate.find(conditions)...

第一个看起来像作品,但是第二个不起作用。

有什么主意吗?

提前谢谢!

1 个答案:

答案 0 :(得分:1)

此查询有很多问题...

首先item.tech-必须是item.skill

接下来,$ gte ... $ in毫无意义。 $ gte表示>=,大于或等于某个值。如果您比较数字,则“内容”必须是数字。像3> = 5解析为false,而3> = 1解析为true。 3> = [1,2,3,4,5]没有意义,因为它解析为true的前三个元素,解析为false的最后2个元素。

最后,$ elemMatch不能这样工作。它测试数组中的每个元素是否符合所有条件。您要编写的内容是:找到一个文档,其中技能数组具有一个子文档,该子文档的技能至少与[技能数组]中的一个匹配,并且级别大于...。即使$ gte条件正确,$ elementMatch和$ in内部的组合也不会比常规$ in更好:

{
    skill: { $in: skills.map(item => item.tech) },
    level: { $gte: ??? }
}

如果要查找具有特定水平或更高水平的技术技能的候选人,则每个技能水平对都应为$或条件:

const conditions = {$or: 
    skills.map(s=>(
        {skill: { $elemMatch: {
            skill:s.skill, 
            level:{ $gte:s.level }
        } } }
    ))
};