2

I currently have a schema which currently looks like:

var User = new Schema({
    id: String,
    firstName: String,
    lastName: String,
    password: String,
    username: String,
    position: [{
          title: String,
          location: String,
          start: String,
          term:Number,
          description:String,
                    date: {type: Date, default: Date.now}
  }]

});

I have two users, each with two embedded position documents.

user1:

"position" : [ 
    {
        "title" : "Web Developer",
        "location" : "Dublin",
        "start" : "May 2017",
        "term" : 6,
        "description" : " Lorem ipsum dolor sit amet, consectetur adipiscing elit. Vivamus quis erat vitae dsit amet, consectetur adipiscing elit. Vivamus quis erat vitae dolor tempus euismod non in mi",
        "_id" : ObjectId("58d6b7e11e793c9a506ffe0f")
    }, 
    {
        "description" : "description",
        "term" : 12,
        "start" : "may 2018",
        "location" : "Dublin",
        "title" : "Web Developer",
        "_id" : ObjectId("58d6af99e4318f4703ceb2af")
    }
],

user2:

 "position" : [ 
        {
            "title" : "Software Engineer",
            "location" : "Cork",
            "start" : "May 2017",
            "term" : 9,
            "description" : " Lorem ipsum dolor sit amet, consectetur adipiscing elit. Vivamus quis erat vitae dolor tempus euismod non in miorem ipsum dolor sit amet, consectetur adipiscing elit. Vivamus quis erat vitae dolor tempus euismod non in mi",
 "_id" : ObjectId("58d6af99e4318f4703cebsju7")

        }, 
        {
            "title" : "Web Developer",
            "location" : "Waterford",
            "start" : "May 2017",
            "term" : 6,
            "description" : " Lorem ipsum dolor sit amet, consectetur adipiscing elit. Vivamus quis erat vitae dsit amet, consectetur adipiscing elit. Vivamus quis erat vitae dolor tempus euismod non in mi",
 "_id" : ObjectId("58d6af99e4318f4703ceb6aj")
        }
    ],

My Query looks like:

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

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

  User.find({'position.title': position}, 'position.$').exec(function (err, result) {
      console.log(result);
      res.send({ results: result });
  });    //


});

When searching 'Web Developer', this will return the first 'Web Developer' entry within the first user, and the 'Web Developer' entry in the second user, but I cant seem to return any subsequent entries and I am just wondering is it a MongoDB issue that I can only return one subdocument that matches per user? Or is there something thats wrong in my code?

The returned object can be seen below, the results object returns the two users, each with one position object, however there should be 3. enter image description here

Suppose I have an array within the positions array, how would I access this?

my current code:

  app.get('/applied', function(req, res){
  User.aggregate(
        {$unwind : "$position"},
        {$unwind : "$position.applied"},
        {$match:{'position.applied.candidate_id': "58dc2bd4e7208a3ea143959e"}}).exec(function (err, result) {
          console.log(result);
        });
        res.render('applied', { title: 'applied'});
});

My Schema:

 position: [{
          title: String,
          location: String,
          start: String,
          term:Number,
          description:String,
          date: {type: Date, default: Date.now},
          applied:[{
                candidate_id: String,
                name: String
            }],
  }],
user
  • 375
  • 2
  • 8
  • 22
  • Possible duplicate of [Retrieve only the queried element in an object array in MongoDB collection](http://stackoverflow.com/questions/3985214/retrieve-only-the-queried-element-in-an-object-array-in-mongodb-collection) – s7vr Mar 28 '17 at 15:31

1 Answers1

6

You can use $unwind for this it will fetch you multiple entries from collection unlike element match or '.' operator which return only first match data

User.aggregate(
        {$unwind : "$position"},
        {$match:{'position.title': position}}).exec(function (err, result) {
      console.log(result);
      res.send({ results: result });
  });
Shumi Gupta
  • 1,377
  • 1
  • 16
  • 26
  • Thanks so much! you've been a real help – user Mar 28 '17 at 16:28
  • I have updated my question as I am stuck again on getting access to a sub sub document.. would you be able to tell me where I am going wrong? The array is returning blank – user Apr 02 '17 at 10:34
  • what is your **position.applied.** applied filed can you share the schema and sample document of applied field. – Shumi Gupta Apr 02 '17 at 10:57
  • 1
    I updated the question to show the schema @Shumi Gupta :) really appreciate your help! – user Apr 02 '17 at 10:59
  • now what you can do is you can apply element match for this as in your applied array you will have only unique candidate so by using element match you can get the result you want. – Shumi Gupta Apr 02 '17 at 11:42
  • is the above syntax that I posted correct? When I changed the $match part to $elemMatch it is returning undefined and I get the error : "UnhandledPromiseRejectionWarning: Unhandled promise rejection (rejection id: 1): MongoError: Unrecognized pipeline stage name: '$elemMatch'" – user Apr 02 '17 at 11:50
  • hey sorry for that actually elemMatch dosent work in aggregate. you can try using **$filter** it might help you in this. Your syntax is correct but position.applied.candidate_id **'.'** dot operator in mongo will match and return you all the documents. Normally we can fetch single document by using **.$** but I am not sure weather it works in aggregation – Shumi Gupta Apr 02 '17 at 12:30
  • visit https://docs.mongodb.com/manual/reference/operator/aggregation/filter/ for more detail about $finter – Shumi Gupta Apr 02 '17 at 12:32
  • Thanks for all your help ! @Shumi Gupta – user Apr 02 '17 at 13:14
  • Still cant seem to get the query right unfortunately :( – user Apr 03 '17 at 10:12
  • @user I have posted an answer on your post try that out. – Shumi Gupta Apr 03 '17 at 10:52