Reputation: 25
I'm trying to query all users that favorited an event. The event Id is stored in the users document in a nested object.
My schema looks like this
{
email: {
type: String,
unique: true,
required: [true, 'Email is required!'],
trim: true,
validate: {
validator(email) {
const emailRegex = /^[-a-z0-9%S_+]+(\.[-a-z0-9%S_+]+)*@(?:[a-z0-9-]{1,63}\.){1,125}[a-z]{2,63}$/i;
return emailRegex.test(email);
},
message: '{VALUE} is not a valid email!',
},
},
role: {
type: String,
enum: ['admin', 'user', 'planner'],
default: 'user',
},
name: {
type: String,
trim: true,
},
username: {
type: String,
trim: true,
unique: true,
},
password: {
type: String,
required: [true, 'Password is required!'],
trim: true,
minlength: [6, 'Password needs to be longer!'],
validate: {
validator(password) {
return password.length >= 6 && password.match(/\d+/g);
},
},
},
picture: {type: String},
favorites: {
events: [
{
type: Schema.Types.ObjectId,
ref: 'Event',
},
],
},
}
How would I write this query?
I've tried all kinds of combinations with $elemMatch
and normal queries aswell
Upvotes: 0
Views: 101
Reputation: 1838
$elemMatch
should be used as an object, but in array favorites.events
each element is String (ObjectID), so you should use $eq
to match each element with String which is ID of event you want.
The solution is:
User.find({
'favorites.events': {
'$elemMatch': {
'$eq': id
}
}
})
Document for $elemMatch
here https://docs.mongodb.com/manual/reference/operator/query/elemMatch/#element-match
And document for $eq
here https://docs.mongodb.com/manual/reference/operator/query/eq/
You should question with simple structure of Mongo. Example, this is my test for you problem
const Schema = mongoose.Schema;
const EventSchema = new Schema({
title: String
})
const UserSchema = new Schema({
username: String,
favorites: {
events: [{
type: Schema.Types.ObjectId,
ref: 'Event',
}]
}
});
const User = mongoose.model('User', UserSchema);
const Event = mongoose.model('Event', EventSchema)
app.get('/users/event/:id', (req, res) => {
const {id} = req.params;
console.log(id);
User.find({
'favorites.events': {
'$elemMatch': {
'$eq': id
}
}
}).then(u => res.send(u)) })
Upvotes: 1