reset password
Author Message
Victor
Posts: 23
Posted 15:09 Nov 18, 2018 |

Hi Professor.

I'm having a bit of a problem.

My userSchema using mongoose has this bit:

events_attended: [
        {
            id: {
                type: mongoose.Schema.Types.ObjectId,
                unique: true,
                ref: 'Event',
                required: true,
                sparse: true
            },
            name: {
                type: String,
                unique: true,
                required: true,
                sparse: true
            }
        }
    ]

This is supposed to hold all events a user has attended.

The problem is that the 'unique' constraint applies across multiple documents rather than within a single array for a single document.

I have checked the mongoose documentation and I've found a way to make it unique within a document but it's still unique across multiple documents too.

Is there a way to make the 'unique' constraint disabled across multiple documents but enabled within an array in a single document?

cysun
Posts: 2935
Posted 15:47 Nov 18, 2018 |

There's a Mongoose plugin that seems to do what you are looking for: https://www.npmjs.com/package/mongoose-unique-array -- it basically adds a custom validator.

It's probably not worth doing though -- just use $addToSet to make sure duplicates are not added.

Victor
Posts: 23
Posted 17:06 Nov 18, 2018 |

There's another issue.

When I try to get all users who attended an event, it works perfectly.

let attendees = await Event.findOne(
            { _id: req.params.id },
            { 'event_attendants': true, _id: false }
        )

gives me something like: 

{
    "event_attendants": [
        {
            "_id": "5bf20860efaf9c1f808c1eb1",
            "id": "5bf20860efaf9c1f808c1ea7",
            "first_name": "Victor",
            "last_name": "Ahuwanya"
        },
        {
            "_id": "5bf2086befaf9c1f808c1eba",
            "id": "5bf2086aefaf9c1f808c1eb7",
            "first_name": "Victor",
            "last_name": "Ahuwanya"
        },
        {
            "_id": "5bf208feefaf9c1f808c1ec7",
            "id": "5bf208fdefaf9c1f808c1ec4",
            "first_name": "Victor",
            "last_name": "Ahuwanya"
        }
    ]
}

But when I try to populate the fields like so:

let attendees = await Event.findOne(
            { _id: req.params.id },
            { 'event_attendants': true, _id: false }
        )
            .populate('event_attendants.id');

I get:

{
    "event_attendants": [
        {
            "_id": "5bf20860efaf9c1f808c1eb1",
            "id": null,
            "first_name": "Victor",
            "last_name": "Ahuwanya"
        },
        {
            "_id": "5bf2086befaf9c1f808c1eba",
            "id": null,
            "first_name": "Victor",
            "last_name": "Ahuwanya"
        },
        {
            "_id": "5bf208feefaf9c1f808c1ec7",
            "id": null,
            "first_name": "Victor",
            "last_name": "Ahuwanya"
        }
    ]
}

I have checked the database and the 'id' filed corresponds to valid Users

Also, my eventSchema has this in it:

event_attendants: [
        {
            id: {
                type: mongoose.Schema.Types.ObjectId,
                ref: 'User',
                required: true
            },
            first_name: {
                type: String,
                required: true,
                trim: true
            },
            last_name: {
                type: String,
                required: true,
                trim: true
            },
        },
    ]

I don't know what I'm doing wrong.

cysun
Posts: 2935
Posted 08:25 Nov 23, 2018 |

Remove the {_id: false} part and see if it works.

Victor
Posts: 23
Posted 09:59 Nov 23, 2018 |

I actually solved this one a long time ago. 

Thanks Professor.