12

MongooseError: Cannot populate path loaned_to because it is not in your schema. Set the strictPopulate option to false to override.

I've tried to join two documents in mongodb using mongoose in nodejs, But unfortunately this error occurs. My mongoose version is 6.0.6

Book Schema

const mongoose = require('mongoose');

const BookSchema = new mongoose.Schema({
    "name": {type: String, required: true},
    "author_name": {type: String, required: true},
    "published_date": {type: Date, required: false},
    "copies": [
        {
            "isbn_number": {type: String, required: true},
            "status": {type: String, required: true, default: "Available"},
            "due_back": {type: Date, required: false},
            "loaned_to": {type: mongoose.Schema.Types.ObjectId, required: false, ref: "User"}
        },
    ]
})

const Book = mongoose.model("Book", BookSchema);
module.exports = Book;

User Schema

const mongoose = require('mongoose');

const UserSchema = new mongoose.Schema({
    "first_name": {type: String, required: true},
    "last_name": {type: String, required: true},
    "phone_number": {type:  String, required: true},
    "address": {type:  String, required: false},
    "user_name":{type: String, required: true},
    "password": {type:  String, required: true},
    "email": {type:  String, required: true},
    "notifications": [
        {
            "notification_id" : {type:"string", required:true},
            "notification": {type: "string", required: true}
        },
    ]
})

const User = mongoose.model("User", UserSchema);
module.exports = User;

My code to join documents

exports.getAllBooks = async (req, res) => {
    try {
        let data = await BookModel.findOne().populate("loaned_to");
        res.status(200).send({data: [...data], success: true})
    } catch (err) {
        console.log(err)
        res.status(404).send({success: false, msg: err.message})
    }
}
Rishi
  • 125
  • 1
  • 1
  • 8
  • path: 'copies.loaned_to' <==== anyone facing this issue . This one is caused due to passing schema name being passed in populate or filed name is wrong. – Shah Vipul Sep 19 '22 at 15:38

2 Answers2

22
exports.getAllBooks = async (req, res) => {
  try {
    let data = await BookModel.findOne().populate({
      path: 'copies.loaned_to',
      select:
        'first_name lastName phone_number address user_name email notifications',
    });
    res.status(200).json({ data: [...data], success: true });
  } catch (err) {
    console.log(err);
    res.status(500).json({ success: false, msg: err.message });
  }
};
2

Use nested populate as in the example below(The example assumes that a Token model has a user which in tern has a role and a role has permissions). This will return a user object associated with the filtered token, with the role the user is assigned to and the permissions assigned to the role.

That is: TokenModel (has relationship to) -> UserModel (has relationship to) -> RoleModel (has relationship to) -> PermissionsModel)

const popObj = {
        path: 'user',
        options: { sort: { position: -1 } },
        populate: {
          path: 'role',
          select: 'name',
          populate: {
            path: 'permissions'
          }
        }
};
const tokenFilter = {is_active: true};
TokenModel.find(userFilter).populate(popObj);
Elijah Baraza
  • 291
  • 4
  • 4