Home > Back-end >  referencing an ObjectId and also storing further information in a nested document in MongoDB
referencing an ObjectId and also storing further information in a nested document in MongoDB

Time:07-11

I'm trying to implement a review functionality for a simple event app I'm developing. I want that the users who attended to an event give feedback to the organizer of the event. I have an organizer schema, and I want to store the ObjectId of the user who gave the feedback, the feedback itself, and optional photo uploads. how do I model this in the Organizer schema? Thanks a lot!

Organizer Schema

const mongoose = require('mongoose')

const organizerSchema = mongoose.Schema(
  {
    username: {
      type: String,
      required: [true, 'Please add a username'],
      unique: true
    },
    email: {
      type: String,
      required: [true, 'Please add an email'],
      unique: true,
    },
    password: {
      type: String,
      required: [true, 'Please add a password'],
    },
    language: { 
      type: String, 
      default: "English"
     },
    images:[{data:Buffer,contentType: String}],
    profilePic: [{data:Buffer, contentType:String}],
    status: String,
    events:[{ type: mongoose.Schema.Types.ObjectId, ref: 'Event' }],
    reviews: [?]
  },
  {
    timestamps: true,
  }
)

module.exports = mongoose.model('Organizer', organizerSchema)

CodePudding user response:

I would create a separate 'Feedback' collection that contains all the feedback given for any event. You can then include fields for the event, the organizer, and the user, so that you can easily query them.

The issue with including reviews under an organiser's collection is that if it grows to thousands of reviews, it might exceed mongoose's document size limits. There may also be situations where you don't want to fetch the organizer's reviews, yet if they are in the organiser's document, you'll have to do so every time you retrieve it.

Something like:

const mongoose = require('mongoose')

const feedbackSchema = mongoose.Schema(
  {
    user: {
      type: mongoose.Schema.Types.ObjectId,
      ref: 'User'
    },
    event: {
      type: mongoose.Schema.Types.ObjectId,
      ref: 'Event'
    },
    organiser: {
      type: mongoose.Schema.Types.ObjectId,
      ref: 'EventOrganizer'
    },
    feedbackText: {
      type: String,
      required: true,
    },
    imageUrls: {
      type: [String],
      required: false
    }
  },
  {
    timestamps: true,
  }
)

// You can index on these fields for faster querying
feedbackSchema.index({user: 1, event: 1, organiser: 1});

module.exports = mongoose.model('Feedback', feedbackSchema)

You can then fetch an organiser's feedback by running:

const Feedback = require('feedbackModel.js')

Feedback.find({organiser: 'XXX'});

Or even join the reviews to each organiser by running something like

const Organizer = require('organizerModel.js');

Organizer.aggregate([
{
   $lookup:
     {
       from: 'Feedback',
       localField: '_id',
       foreignField: 'organizer',
       as: 'reviews'
     }
}
]

  • Related