Search code examples
node.jsmongodbmongoosesubquerysubdocument

$unwind nested document and $match


I have a nested document which looks like:

    var User = new Schema({
    id: String,
    position: [{
        title: String,
           applied:[{
                candidate_id: String,
                name: String
        }],
        }],

What I am looking to do is return all of the 'applied' subdocuments which match a certain 'candidate_id'

What I have so far:

  app.get('/applied', function(req, res){

  var position = "58dc2bd4e7208a3ea143959e";

  User.aggregate(
        {$unwind : "$position"},
        {$unwind : "$position.applied"},
        {$match:{'position.applied.candidate_id': position}}).exec(function (err, result) {
          console.log(result);
        });
        res.render('applied', { title: 'applied',layout:'candidate'});
});

I have another function which returns all the positions that match, and that code works:

app.post('/search', function (req, res) {

  var position = new RegExp(req.body.position, 'i');
  var location = new RegExp(req.body.location, 'i');

  User.aggregate(
        {$unwind : "$position"},
        {$match:{'position.title': position,'position.location':location}}).exec(function (err, result) {
      console.log(result);
      res.send({ results: result });
  });
});

So basically I am struggling with getting a sub-sub-document. Any idea where I'm going wrong?

Sample data:

{
"_id" : ObjectId("58c2871414cd3d209abf5fc9"),
"position" : [ 
    {
        "_id" : ObjectId("58d6b7e11e793c9a506ffe8f"),
        "title" : "Software Engineer",

        "applied" : [ 
            {
                "candidate_id" : "58d153e97e3317291gd80087",
                "name" : "Sample user"

            }, 
            {
                "candidate_id" : "58d153e97e3317291fd99001",
                "name" : "Sample User2"

            }
        ]
    }, 
    {
        "_id" : ObjectId("58c2871414cd3d209abf5fc0"),
        "title" : "Software Engineer",

    }
],

}

What is going on above is there 2 positions, one of which (first entry) has 2 applied candidates, What I need to do is return the nested object if it matches the mongoose query.


Solution

  • Your code seems fine to me I have implemented same and it works for me only possible issue can be that your position="58dc2bd4e7208a3ea143959e" it might be talking it as a string just convert it to objectId by using the following code and check it should work for you.

    var mongoose = require('mongoose');
    
         var position = mongoose.Types.ObjectId("58dc2bd4e7208a3ea143959e");
    
              User.aggregate(
                    {$unwind : "$position"},
                    {$unwind : "$position.applied"},
                    {$match:{'position.applied.candidate_id': position}}).exec(function (err, result) {
                      console.log(result);
                    });
                    res.render('applied', { title: 'applied',layout:'candidate'});
            });