0

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

2
  • db.collection.find({ "favorites.events": userId }) Commented Dec 17, 2018 at 1:26
  • 1
    Thanks @AnthonyWinzlet surprisingly that worked, the problem was I was passing a string to it instead of passing a object id when I tried it before! Commented Dec 17, 2018 at 1:37

1 Answer 1

1

$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)) })
Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.