Search code examples
javascriptmongodbmongoose

Use a field to refer to different collections


I have a Comment model and comments can be added to a Post or another Comment. Instead of defining two optional parentPost & parentComment fields, I want to define a parentCollection field that points to either the Post or Comment models, and then an ID to the object. I'm new to Mongoose/MongoDB. Is this possible and are there caveats to this approach?

// What I have
const commentSchema = new Schema({
  parentComment: {type: Schema.Types.ObjectId, ref: 'Comment'},
  parentPost: {type: Schema.Types.ObjectId, ref: 'Post'}
})
// What I want
const commentSchema = new Schema({
  parentModel: {}, // Not sure what to put here, String maybe?
  parentID: {type: Schema.Types.ObjectId} // Maybe ref could point to parentModel?
})

My goal is to reduce the number of fields for models with many possible parent types. Is this ever done in practice or is the first method with multiple fields the common approach?


Solution

  • you can have Dynamic References using refPath

    for example in your use case can do something like

    const postSchema = mongoose.Schema({
        //....
    });
    
    const commentSchema = mongoose.Schema({
        parentID: {
          type: mongoose.Schema.Types.ObjectId,
          required: true,
          refPath: 'parentModel'
        },
        parentModel: {
          type: String,
          required: true,
          enum: ['Comment', 'Post']
        },
        //....
    });
    
    const Post = mongoose.model('Post', postSchema);
    const Comment = mongoose.model('Comment', commentSchema);