OllyBarca
OllyBarca

Reputation: 1531

Mongoose dynamic sub document schema

I have an Inquiry schema:

const inquirySchema = new mongoose.Schema({
  client: [{ type: mongoose.Schema.Types.ObjectId, ref: 'Client' }],
  data: dynamicSchema?
}, {
  timestamps: true
});

I would like to populate the "data" property field with a sub-document, but I want it to accept different sub-document schemas. I have an "Event" and a "Property" child schema which can be inserted as "data". How do I allow this in my Inquiry schema? It seems I have to actually specify WHICH sub-document schema it expects...

My Child schemas:

const eventSchema = new mongoose.Schema({
  name: { min: Number, max: Number },
  date: { type: Date },
  zone: { type: String }
});

const propertySchema = new mongoose.Schema({
  price: { min: Number, max: Number },
  status: { type: String },
  zone: { type: String }
});

Upvotes: 0

Views: 981

Answers (1)

Ravi Shankar Bharti
Ravi Shankar Bharti

Reputation: 9268

you can make your data as type : ObjectId without defining any reference in the schema, and when you want to populate them, use path and model in the populate to populate from different collection, but you must have a logic for choosing which collection to populate from.

Here is how you can do the same:

inquirySchema

const inquirySchema = new mongoose.Schema({
  client: [{ type: mongoose.Schema.Types.ObjectId, ref: 'Client' }],
  data: { type: mongoose.Schema.Types.ObjectId }
}, {
  timestamps: true
});

Populating data

if(isEvent)
{
    //Populate using Event collection
    Inquiry.find({_id : someID}).
            populate({path : 'data' , model : Event}).
            exec(function(err,docs){...});
}
else if(isProperty)
{
    //Populate using Property collection
    Inquiry.find({_id : someID}).
            populate({path : 'data' , model : Property}).
            exec(function(err,docs){...});
}

Upvotes: 1

Related Questions