Opeyemi Odedeyi
Opeyemi Odedeyi

Reputation: 770

Setting up a complex comment model in NodeJs and mongoose

I am setting up a comment model where users can post comments reference and can also reply. the complication comes with the reply part. I want users to be able to reply to comments or others' replies, and I am lost on how to set up my model for that.

How should I set up my model to be able to capture that data in my reply?

also, any other suggestion would be appreciated

Here is the model I am currently setting up

const mongoose = require('mongoose')

const commentSchema = new mongoose.Schema({
    owner: {
        type: mongoose.Schema.Types.ObjectId,
        required: true,
        ref: 'User'
    },
    reference: {
        type: mongoose.Schema.Types.ObjectId,
        required: false,
        ref: 'Project' || null,
        default: false
    },
    body: {
        type: String,
        required: true,
        trim: true
    },
    reply: {
        owner: {
            type: mongoose.Schema.Types.ObjectId,
            required: false,
            ref: 'User'
        },
        body: {
            type: String,
            required: true
        }
    }
}, {
    timestamps: true
})

const Comment = mongoose.model('Comment', commentSchema)

module.exports = Comment

Upvotes: 1

Views: 162

Answers (1)

grodzi
grodzi

Reputation: 5703

If you are thinking about a model where we have

some post
>commentA
  >replyA-a
    >replyA-a-a
      >replyA-a-a-a
  >replyA-b
>commentB
>commentC

I would aggregate everything for the corresponding entity

Comment {
  user,
  body,
  replies: [Comment] // pattern composite
}
EntityComment { // only persist this one
  reference: { id, type: post|topic|whatever },
  comment: [Comment]
}

Props are:

  • an entityComment can grow big (is this problematic?)
  • no need for multiple fetch, everything's there
  • easy to "hide" some comments and just show its count (array length)

If record entityComment becomes too big (the max record length seems to be 16MB so likely not be the limit, but maybe the payload is slow to load), then

  1. we can think of saving each comment (using replies: [{ ref: Comment, type: ObjectId)}])
  2. but maybe a better idea is to use a reference for body (body: [ref: CommentBody, type: ObjectId])

The reason is body is likely the culprit (datasize wise), and this would allow to

  • keep everything nested in entityComment
  • delay the fetch of the bodies we are interested in (not the whole hierarchy)

There are tradeoffs:

  1. is fine for read
  2. is simpler for writes (just update/delete a singular comment)

Upvotes: 1

Related Questions