0

I have to filter candidate documents by an array of objects.

In the documents I have the following fields:

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

When I make the request I get other array of skills, for example:

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

So I need to build a query to get the documents that contains this skill and a greater or equal level.

I try doing the following:

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

Candidate.find(conditions)...

The first one seems like works but the second one doesn't work.

Any idea?

Thank you in advance!

1 Answer 1

1

There are so many problems with this query...

First of all item.tech - it had to be item.skill.

Next, $gte ... $in makes very little sense. $gte means >=, greater or equal than something. If you compare numbers, the "something" must be a number. Like 3 >= 5 resolves to false, and 3 >= 1 resolves to true. 3 >= [1,2,3,4,5] makes no sense since it resolves to true to the first 3 elements, and to false to the last 2.

Finally, $elemMatch doesn't work this way. It tests each element of the array for all conditions to match. What you was trying to write was like : find a document where skills array has a subdocument with skill matching at least one of [array of skills] and level is greater than ... something. Even if the $gte condition was correct, the combination of $elementMatch and $in inside doesen't do any better than regular $in:

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

If you want to find candidates with tech skills of particular level or higher, it should be $or condition for each skill-level pair:

const conditions = {$or: 
    skills.map(s=>(
        {skill: { $elemMatch: {
            skill:s.skill, 
            level:{ $gte:s.level }
        } } }
    ))
};
Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.