0

I am trying to populate a object myObj. After saving values to 'a' object, I am able to see the data for 'myObj' in the db. But when I query for the obj 'a', its not pulling the 'myObj' data. My Schema is as below.

var a= new Schema({
    b: 'Date',
    c: {
        d: {
            type: Schema.ObjectId,
            ref: 'Student'
        },
        myObj: {
            type: [{
                type: Schema.ObjectId,
                ref: 'Exam'
            }],
            select: true
        },
    }
});

Exam Schema

var ExamSchema= new Schema({
    name: String,        
    subject: {
        type: [{
            name: String, 
            marks: Number            
        }],
        select: false
    }
});

My querying method:

exports.a = function(req, res, next, id) {
    A //model of 'a'
        .findOne({
            _id: id
        })
        .populate('c.d c.myObj')
        .exec(function(err, aObj) {
            if (err) return next(err);
            if (!aObj) return next(new Error('Failed to load  ' + id));            
            req.a = aObj;
            next();
        });
};

Expected Output:

var a = new Schema({
    b: "2014-07-10T02:30:00.005Z",
    ,
    c: {
        d: {
            name: 'Hari',
            age: 10
        },
        myObj: {
            [{
                name: 'Quaterly',
                subject: {
                    [{
                        name: 'English',
                        marks: 100
                    }, {
                        name: 'Maths',
                        marks: 90
                    }, {
                        name: 'Science',
                        marks: 100
                    }],
                    select: false
                }
            }, {
                name: 'Half-Yearly',
                subject: {
                    [{
                        name: 'English',
                        marks: 100
                    }, {
                        name: 'Maths',
                        marks: 90
                    }, {
                        name: 'Science',
                        marks: 100
                    }],
                    select: false
                }
            }],
            select: true
        },
    }
});

**Actual Output:**

    var a = new Schema({
        b: "2014-07-10T02:30:00.005Z",
        ,
        c: {
            d: {
                name: 'Hari',
                age: 10
            },
            myObj: []
        }
    });

Please let me know where I am wrong. Thanks.

2
  • 1
    Shouldn't that be populate('c.d c.myObj')? Commented Jul 10, 2014 at 3:23
  • I have changed it. But the issue remains. Commented Jul 10, 2014 at 3:33

1 Answer 1

2

This should be working, here is a cut down sample to test and compare and see what you might actually be doing differently:

var async = require('async'),
    mongoose = require('mongoose'),
    Schema = mongoose.Schema;


mongoose.connect('mongodb://localhost/throw');

var oneSchema = new Schema({
  name: String
});

var twoSchema = new Schema({
  name: String
});

var testSchema = new Schema({
  name: String,
  c: {
    d: { type: Schema.Types.ObjectId, ref: "One" },
    e: [{ type: Schema.Types.ObjectId, ref: "Two" }]
  }
});

var Test = mongoose.model( "Test", testSchema, "test" );
var One =  mongoose.model( "One", oneSchema, 'one' );
var Two =  mongoose.model( "Two", twoSchema, 'two' );


var test = new Test({ name: "test" });

var one = new One({ name: "one" });

var two = new Two({ name: "two" });
var three = new Two({ name: "three" });

test.c.d = one;
test.c.e.push(two,three);

async.series([

  // Remove prior
  function(callback) {
    async.each([Test,One,Two],function(model,complete) {
      model.remove(function(err) {
        if (err) throw err;
        complete();
      });
    },function(err) {
      if (err) throw err;
      callback();
    });
  },

  // Save new
  function(callback) {
    async.each([test,one,two,three],function(model,complete) {
      model.save(function(err) {
        if (err) throw err;
        complete();
      });
    },function(err) {
      if (err) throw err;
      callback();
    });
  },


  // Unpopulated
  function(callback) {
    Test.findOne()
      .exec(function(err,obj) {
        if (err) throw err;

        console.log( "Before: %s", JSON.stringify( obj, undefined, 4 ) );
        callback();
      });
  },

  // Populated

  function(callback) {
    Test.findOne()
      .populate("c.d c.e")
      .exec(function(err,obj) {
        if (err) throw err;

        console.log( "After: %s", JSON.stringify( obj, undefined, 4 ) );
        callback();
      });
  }

],function(err) {
  if (err) throw err;
  process.exit();
});

Which should produce results along the lines of:

Before: {
    "_id": "53be11986c64035664e4d73a",
    "name": "test",
    "__v": 0,
    "c": {
        "d": "53be11986c64035664e4d73b",
        "e": [
            "53be11986c64035664e4d73c",
            "53be11986c64035664e4d73d"
        ]
    }
}
After: {
    "_id": "53be11986c64035664e4d73a",
    "name": "test",
    "__v": 0,
    "c": {
        "d": {
            "_id": "53be11986c64035664e4d73b",
            "name": "one",
            "__v": 0
        },
        "e": [
            {
                "_id": "53be11986c64035664e4d73c",
                "name": "two",
                "__v": 0
            },
            {
                "_id": "53be11986c64035664e4d73d",
                "name": "three",
                "__v": 0
            }
        ]
    }
}
Sign up to request clarification or add additional context in comments.

2 Comments

Does these lines add test.c.d = one; test.c.e.push(two,three); the structure of one to c.d and structure of two and three to c.e? if not what do they actually mean?
@sabari the field c.d in object test is a single ObjectId reference so it is a simple assignment. c.e is an array of ObjectId values, so you "push" to add items to an array. Actually the problem with your populate is you have an extra field there. So you need to populate with the paths "c.d c.myObj.type". You would honestly be better off removing that "select" field at that level.

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.