Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

about mongoose populate relation a string field

I have two Schema

1 - User

UserSchema = new db.Schema({
    email:  {type: String, required: true},
    pass:   {type: String, required: true},
    nick:   {type: String, required: true},
    admin:  {type: String, default: ''},
    reg:    {type: Date, default: Date.now}
});

2 - Article

ArticleSchema = new db.Schema({
    title:      {type: String, required: true},
    alise:      {type: String},
    time:       {type: Date, defaults: Date.now},
    view:       {type: Number, defaults: 0},
    author:     {type: String},
    content:    {type: String},
    classes:    {type: db.Schema.Types.ObjectId, ref: 'Classes'},
    user:       {type: String, ref: 'User'}
});

I want ArticleSchema user field relation UserSchema nick.

my code:

Model.findOne({}).populate('classes user').exec(function(err, res){
    if(err){
        cb(err);
    }else{
        cb(null, res);
    }
});

This is not working

message: 'Cast to ObjectId failed for value "tudou" at path "_id"'

What should I do?

like image 213
tudou Avatar asked Sep 23 '15 15:09

tudou


2 Answers

Apparently you are using Mongoose, right? If yes, to do it you must use db.Schema.Types.ObjectId in the ArticleSchema user field. So, your ArticleSchema should looks like this:

ArticleSchema = new db.Schema({
    title:      {type: String, required: true},
    alise:      {type: String},
    time:       {type: Date, defaults: Date.now},
    view:       {type: Number, defaults: 0},
    author:     {type: String},
    content:    {type: String},
    classes:    {type: db.Schema.Types.ObjectId, ref: 'Classes'},
    user:       {type: db.Schema.Types.ObjectId, ref: 'User'}
});



According to documentation:

There are no joins in MongoDB but sometimes we still want references to documents in other collections. This is where population comes in.


So, taking a look here, we can do something like that:

//To create one user, one article and set the user whos created the article.
var user = new UserSchema({
    email : '[email protected]',
    nick : 'danilo'
    ...
});
user.save(function(error) {
    var article = new ArticleSchema({
        title : 'title',
        alise : 'asdf',
        user : user,
        ...
    });
    article.save(function(error) {
        if(error) {
            console.log(error);
        }
    });
}


And to find an article that was created for danilo:

ArticleSchema
.find(...)
.populate({
  path: 'user',
  match: { nick: 'danilo'},
  select: 'email nick -_id'
})
.exec()



I suggest you to read about mongoose populate here

like image 172
danilodeveloper Avatar answered Oct 12 '22 05:10

danilodeveloper


As of 4.5.0 You can use populate virtuals : http://mongoosejs.com/docs/populate.html#populate-virtuals

UserSchema = new db.Schema({
    email:  {type: String, required: true},
    pass:   {type: String, required: true},
    nick:   {type: String, required: true},
    admin:  {type: String, default: ''},
    reg:    {type: Date, default: Date.now}
});

ArticleSchema = new db.Schema({
    title:      {type: String, required: true},
    alise:      {type: String},
    time:       {type: Date, defaults: Date.now},
    view:       {type: Number, defaults: 0},
    author:     {type: String},
    content:    {type: String},
    classes:    {type: db.Schema.Types.ObjectId, ref: 'Classes'},
    user: {type: String}
});

ArticleSchema.virtual('_user', {
  ref: 'User', // The model to use
  localField: 'user', // Find people where `localField`
  foreignField: 'email', // is equal to `foreignField`
  // If `justOne` is true, 'members' will be a single doc as opposed to
  // an array. `justOne` is false by default.
  justOne: true,
  options: { sort: { name: -1 }, limit: 5 }
});

var User = mongoose.model('User', UserSchema);
var Article = mongoose.model('Article', ArticleSchema);

Article.find({}).populate('_user').exec(function(error, articles) {
  /* `articles._user` is now an array of instances of `User` */
});
like image 24
M. Gara Avatar answered Oct 12 '22 04:10

M. Gara