Search code examples
mongodbdatabase-designmongoosemongoose-schemanon-relational-database

MongoDB: How to make a reference to a variable path?


I have a schema called PageSection. PageSection embeds an array of the Schema ContentItem. A content item should reference to a documents of other collections, which can be variable - like Text, Picture, Link, Checkbox, ...

var PageSection = new mongoose.Schema({
  title: String,
  order: Number,
  contentItems: [{
    order: Number,
    element: {
      type: mongoose.Schema.Types.ObjectId,
      path: "Path_to_various_models"
    }
  }]
});

Is this possible? Or is there an better way to that kind of variable references?

Thanks!

Edit: Thanks for advice for using discriminators Swagata. I didn't knew that inheritance mechanism. But anyway, I found that solution a bit complex.

I now use a solution, where ContentItem contains a field for each type of content item. Maybe its more a workaround, than a solution.

var PageSection = new mongoose.Schema({
  title: String,
  order: Number,
  contentItems: [{
    order: Number,
    text: {
      type: mongoose.Schema.Types.ObjectId,
      path: "Text"
    },
    picture: {
      type: mongoose.Schema.Types.ObjectId,
      path: "Picture"
    },
    link: {
      type: mongoose.Schema.Types.ObjectId,
      path: "Link"
    }
  }]
});

Solution

  • I'm not sure of the question as I pointed that out in the comment before. I think you're looking for populate if 'Path to various models' means 'references to other models'. According to here, you can do something like

    var PageSection = new mongoose.Schema({
      title: String,
      order: Number,
      contentItems: [{
        order: Number,
        element: mongoose.Schema.Types.ObjectId,
        path: { type: Schema.Types.ObjectId, ref: 'Story' }
      }]
    });
    

    Now, I understand that this is only for one type for one reference there, path cant be only stories.

    If you have elements that come from single collection with a base type and multiple derived type you can go for Mongoose discriminator method here. You can find more in here too. In this technique, you'd need to

    1. Create a base schema for all contentItem path
    2. Use a discriminator to discriminate

    I still don't suggest this as it would lead to bad design.

    And according to here it's better to keep the references at bay with defined types.

    You can still manage references with your own way in the contentItems array with a id and collection/ref field and I think that would be better in this case.

    Hope it helps