Can a reference field in a Mongoose schema pertain to more than one data model?

When a field in a mongoose schema contains a reference to some document in another data model/collection (as in the example below), is it possible for the ‘ref’ field to have more than one possible value?

const documentSchema = Schema({
  _id: Schema.Types.ObjectId,
  title: String,
  date: Date,
  references: [{ type: Schema.Types.ObjectId, ref: 'Person' }]
});

Suppose that instead of a model called ‘Person’, there were instead two or more possible models whose documents we might wish to reference (e.g., ‘Student’, ‘Professor’, ‘Administrator’…), depending on the case. Is there a way to specify that the data model of this reference could be ‘Student’, ‘Professor’, or ‘Administrator’, or is that simply not allowed?

2 Likes

Hi,

Can you try to use Mixed:

const documentSchema = Schema({
  _id: Schema.Types.ObjectId,
  title: String,
  date: Date,
  references: [{ type: Schema.Types.Mixed }]
});
2 Likes

But this is essentially allowing the type to be “any” object. I want the type to be an ObjectId of some document; it’s just that I want to be able to reference the id’s of documents from more than one model and therefore more than one collection (Student, Professor, and Administrator in this example). If I set the type to Schema.Types.Mixed, how will Mongo know which collection to query for the id that is stored there?

Or do you mean that instead of storing an ObjectId there, I would be storing an object that can have one of these three possible forms?

{ type: Schema.Types.ObjectId, ref: 'Student' }
{ type: Schema.Types.ObjectId, ref: 'Professor' }
{ type: Schema.Types.ObjectId, ref: 'Administrator' }

(If that is the case, then I guess the answer to my original question would be “no, it isn’t possible to have ‘ref’ refer to more than one data model at a time”.)

You can create Dynamic Reference with refPath. In that case you would need to create one additional property that would store the actual reference. When populating, Mongoose will check the value in that new field. You can do it like this:

const documentSchema = Schema({
  _id: Schema.Types.ObjectId,
  title: String,
  date: Date,
  references: { type: [Schema.Types.ObjectId], refPath: 'model_type' },
  model_type: {  type: String, enum: ['Student', 'Professor', 'Administrator' ], required: true }
});
7 Likes

@NeNaD thanks, this is exactly the kind of solution I was looking for

1 Like

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