Reference sub document and then populate that subdocument on .find()

Hi, am new here.
what i am trying to do is to reference a sub-document and then populate on the .find() function.

My branch schema

const branchSchema = mongoose.Schema(
  {
    office: [
      {
        ...multiple office detail
      },
    ],
  },
  { timestamps: true }
)

const Branch = mongoose.model("Branch", branchSchema)
export default Branch

My company schema

const companySchema = mongoose.Schema(
  {
    office: {
      type: mongoose.Schema.Types.ObjectId,
      ref: "Branch.office",
    },
    status: {
      type: String,
      required: true,
      default: "active",
    },
    createdBy: {
      type: mongoose.Schema.Types.ObjectId,
      required: true,
      ref: "User",
    },
  },
  { timestamps: true },
)

const Company = mongoose.model("Company", companySchema)
export default Company

Query and error:

const offices = await Company.find().populate("office")
ERROR I GET: 
{
    "error": "failed",
    "message": "MissingSchemaError: Schema hasn't been registered for model \"Branch.office\".\nUse 
     mongoose.model(name, schema)"
}

Hi :wave: @Rickal_Hamilton,

Welcome to the MongoDB Community forums :sparkles:

This error is occurring because the schema for the office field in your companySchema has not been registered with the mongoose model. In your companySchema, you have set the ref field of the office property to “Branch.office”. This is not the correct way to reference the office field in the branchSchema. Instead, you should reference the Branch model and its office field as follows:

office: {
  type: mongoose.Schema.Types.ObjectId,
  ref: "Branch",
},

This will tell Mongoose to populate the office field with the data from the Branch model.

To read more about it refer to the Mongoose documentation link.

Also, make sure that you have imported the Branch model into the file where your Company model is defined. You can do this by adding the following line at the top of your file:

import Branch from "./path_to_branchModel"

I hope it helps!

Best,
Kushagra

1 Like

i know of that way but that returns the big array of offices stored in branch i don’t want the entire array of offices i am trying to get to a single office by referencing that branch _id Branch.office is there no way to do this? what if i have 1000 office stored in the array of offices—>

 Branch{offices:[
{....1000 office sub doc}]

Hi @Rickal_Hamilton,

Here office is a field as per your branch model which contains an array of sub-documents.

The ref option is what tells Mongoose which model to use during population. So, the model is branch which will be used to populate the office field. To read more refer to this link.

If you want to populate the sub-document from the large array set by referencing that branch _id, you can do as following:

Company.find({ office: { $elemMatch: { _id: 'abc123' } } })
  .populate("office") 
  .exec((err, offices) => {
    if (err) {
      console.log(err);
      return;
    }
    console.log(offices);
  });

Here the $elemMatch operator is used to search for the _id of the branch you wish to populate.

Please note this is not the tested code, it’s just for your reference please test this as per your requirement.

I hope it helps!

Best,
Kushagra

1 Like

This topic was automatically closed 5 days after the last reply. New replies are no longer allowed.