简体   繁体   中英

Referencing another schema in Mongoose WITH extra fields

var UserSchema = new Schema({
  job : [{
    type : mongoose.Schema.Types.ObjectId,
    experience : String,
    grade : String,
    ref: 'Company'}]
});

User can have several jobs. When I add a job to the user, I do like this :

If I have :

req.body.job == {type : company._id, experience : "bla bla", grade : "smth"}

and

function addJob(req, res, next) {

  var userId = req.user._id;
  var job = req.body.job;
  return User.findById(userId).exec()
    .then(user => {
      user.job.push(job);
      return user.save()
        .then(handleEntityNotFound(res))
        .then(respondWithResult(res))
        .catch(handleError(res));
    });
}

I got an error :

Unhandled rejection CastError: Cast to ObjectId failed for value "[object Object]" at path "job"

But if i do :

req.body.job == {type : company._id, experience : "bla bla", grade : "smth"}

with

 function addJob(req, res, next) {

      var userId = req.user._id;
      var job = req.body.job;
      return User.findById(userId).exec()
        .then(user => {
          user.job.push(job.type); // <----------
          return user.save()
            .then(handleEntityNotFound(res))
            .then(respondWithResult(res))
            .catch(handleError(res));
        });
    }

It works but experience and grade are undefined. How can I specify those fields ?


EDIT :

So I changed UserSchema like :

var UserSchema = new Schema({
  job : [{
    _company : {
      type : mongoose.Schema.Types.ObjectId,
      ref: 'Company'
    },
    experience : String,
    grade : String
    }]
});

And I tried :

//req.body.job == {_company:{type : company._id}, experience : "bla bla", grade : "smth"}

function addJob(req, res, next) {

  var userId = req.user._id;
  var job = req.body.job;
  return User.findById(userId).exec()
    .then(user => {
      user.job.push(job);
      return user.save()
        .then(handleEntityNotFound(res))
        .then(respondWithResult(res))
        .catch(handleError(res));
    });
}

I got an 500 (Internal Server Error) error from server

BUT

//req.body.job == {_company:{type : company._id}, experience : "bla bla", grade : "smth"}

function addJob(req, res, next) {

  var userId = req.user._id;
  var job = req.body.job;
  return User.findById(userId).exec()
    .then(user => {
      user.job.push(job._company); //<-----------------
      return user.save()
        .then(handleEntityNotFound(res))
        .then(respondWithResult(res))
        .catch(handleError(res));
    });
}

Works without error. However there is still nothing about grade and experience field in mongodb...

The field "type" is reserved by Mongoose, then

{
    type : mongoose.Schema.Types.ObjectId,
    experience : String,
    grade : String,
    ref: 'Company'
}

is describing an entity with a type of ObjectId, referencing a Company (this one is used with .populate). Unfortunately, since it is saved in MongoDB as an ObjectId, the other fields will be ignored.

You can then choose to reference the company in one of the fields, and be able to retrieve the extra bits of information with a JobSchema like :

{
    _company : {type: mongoose.Schema.Types.ObjectId, ref: 'Company'}
    experience : String,
    grade : String
}

You will be able to populate the _company field of your jobs without losing the "experience" and "grade" information


After your edition :

With the given JobSchema :

{
    _company : {type: mongoose.Schema.Types.ObjectId, ref: 'Company'}
    experience : String,
    grade : String
}

Your job instance should look like {_company: ObjectId("......."), experience : "blabla", grade: "smth"}. Then your req.body.job should be {_company: company._id, experience : "bla bla", grade : "smth"}

In your first addJob, you have a 500 error because you are asking MongoDB to cast a document that looks like {type: ObjectId("....")} into an ObjectId.

The second addJob doesn't trigger an error because you are uploading a document that looks like {type: ObjectId("...")} (and losing the grade and experience fields by the way) and none of your Schema fields are required so mongoose is ignoring your field type and uploads an empty object into your collection.

tl;dr: It should be :

// req.body.job == {_company: company._id, experience : "bla bla", grade : "smth"}

function addJob(req, res, next) {
    var userId = req.user._id, 
        job    = req.body.job;

    return User.findById(userId)
               .exec()
               .then(
                   user => {
                       user.job.push(job);
                       return user.save()
                                  .then(handleEntityNotFound(res))
                                  .then(respondWithResult(res))
                                  .catch(handleError(res));
                   }
               );
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM