'How to prevent duplicates in nested array mongoose?

I am trying to prevent duplicates on today's date when the students are taking attendance.

For example, every day students are to take attendance but when a student named John submit multiple times for today's attendance, my MongoDB would have many duplicate entries for John's today's attendance.

Here is my schema:

const attendanceSchema = mongoose.Schema({
    courseTitle: { type: String, trim: true },
    courseStartDate: {type: Date},
    courseEndDate: {type: Date},
    enrollment: [{
        studentID: { type: String, trim: true},
        studentName: { type: String, trim: true },
        attendance: [{
            datenumber:{type:Number},
            attendanceDate: { type: Date},
        }],
    }],
}, { timestamps: true });

Here is my node/express code:

router.post('/attendance/takeattendance', async (req, res) => {

 const todaydatenumber = moment().format("YYYYMMDD")

  const attendanceTaking = {
          datenumber: datenumber,
          attendanceDate: moment().format('YYYY-MM-DD, hh:mm:ss a')
    }

        await Attendance.findOneAndUpdate({ _id: {"$eq": courseid}},
          {
            $push: {
              "enrollment.$[enroll].attendanceTaking":attendanceTaking
            },
          },{arrayFilters:[{ "enroll._id": req.params.studentid }]})
          return res.json({ statusCode: "200", msg: 'Attendance taken for today! Thanks.' });
      } 
}

How should I prevent the duplicate date for today's attendance? Thanks

Update:

When I tried to query for today date 20220330 using this code here:

   let attendanceExist = await Attendance.findOne({ enrollment: { $elemMatch: { studentUUID: { "$eq": student.studentUUID }, "enrollment.attandanceTaking": { $elemMatch: { datenumber: { "$eq": 20220330 } } } } } })

Here is the data I am trying to query:

_id : 6210834ce3a7b51ad5bde65e
courseTitle : "Some Course Title"
courseStartDate:2022-02-20 07:30:00.000
courseEndDate:2022-02-24 07:30:00.000
attendanceStatus:"Open"
enrollment:Array
    0:Object
        studentUUID:"6506de7b0d32492c878307a1992f54e8"
        studentName:"John Doe"
        _id:6242d542af9da06f9e69eb1f
        
        attendanceTaking:Array
            0:Object
                datenumber:20220329
                attendanceDateAM:2022-03-29 12:14:40.000
                attendanceDatePM:1900-01-01 01:04:35.000
                _id:6243d93072c09377877ee501
            1:Object
                datenumber:20220330
                attendanceDateAM:2022-03-30 13:44:26.000
                attendanceDatePM:1900-01-01 01:04:35.000
                _id:6243ee3a7c0a73ed7ed49c54
createdAt:2022-02-19 13:42:36.946
updatedAt:2022-03-30 13:44:43.786
__v:0

But when I console.log(attendanceExist), I am getting null when I should be getting some results



Solution 1:[1]

You can add conditions depending on existing data something like this

    let attendanceExist = await Attendance.find({enrollment: {
    $elemMatch: {
      studentId: //id,attandance: {$elemMatch: {dateNumber://date}}
    }}})
    
    if(attendanceExist)
    {
    return
    }
    
    else{
    //your insert query
    }

Suggestion - You can handle it with front end also, if a student marked the attendance for today the button should be disabled or hidden after marking

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1