Pig
Pig

Reputation: 2122

Mongoose: Difference between referencing "Schema.ObjectId" instead of directly using the schema name?

Suppose I have the following MessageSchema model:

    var MessageSchema = new Schema({
      userId: String,
      username: String,
      message: String,
      date: Date 
    });
    mongoose.model('Message', MessageSchema)   

Can someone tell me the difference between the following two implementations of the Meetings model? Thanks.

    var Meetings = new Schema({
      _id: ObjectId,
      name: String,
      messages: [MessageSchema],
      ... 
    });

    var Meetings2 = new Schema({
      _id: ObjectId,
      name: String,
      messages: [{type: Schema.ObjectId, ref: 'Message'}],
      ... 
    });

Upvotes: 1

Views: 236

Answers (2)

chridam
chridam

Reputation: 103305

The main difference is that Meeting model is embedding the MessageSchema (denormalization) whilst the Meeting2 model references it (normalization). The difference in choice boils down to your model design and that depends mostly on how you query and update your data. In general, you would want to use an embedded schema design approach if the subdocuments are small and the data does not change frequently. Also if the Message data grows by a small amount, consider denormalizing your schema. The embedded approach allows you to do optimized reads thus can be faster since you will only execute a single query as all the data resides in the same document.

On the other hand, consider referencing if your Message documents are very large so they are kept in a separate collection that you can then reference. Another factor that determines the referencing approach is if your document grows by a large amount. Another important consideration is how often the data changes (volatility) versus how it's read. If it's updated regularly, then referencing is a good approach. This way enhances fast writes.

You can use a hybrid of embedding and referencing i.e. create an array of subdocuments with the frequently accessed data but with a reference to the actual document for more information.

The general rule of thumb is that if your application's query pattern is well-known and data tends to be accessed only in one way, an embedded approach works well. If your application queries data in many ways or you unable to anticipate the data query patterns, a more normalized document referencing model will be appropriate for such case.

Upvotes: 1

user2441535
user2441535

Reputation:

Meetings messages field contains an array of Message object, while Meetings2 messages field contains an array of Message Id's.

var Meetings2 = new Schema({
      ...
  messages: [{type: Schema.ObjectId, ref: 'Message'}],
      ... 
});

can be written as

var Meetings2 = new Schema({
      ...
  messages: [Schema.ObjectId],
      ... 
});

The ref is just a helper function in mongoose, making it easier to populate the messages.

So in summary. In Meetings you embed the messages in an array, while in Meetings2 you reference the messages.

Upvotes: 1

Related Questions