Search code examples
mongoosemongodb-query

Difference between $elemMatch and $in


I am building a chat app using mongoose and nestjs. This is my first attempt of using mongo as database so I am having trouble differentiate which mongo query should I be using.

The following function is to find one on one chat between logged in user and other user. I tested the two approach in Insomnia and they come back the same result.

Approach 1

async findOneOnOneChat(currentUserId, userId) {
  const oneOnOneChat = await this.chatModel
    .find({
      isGroupChat: false,
    })
    .and([
      { users: { $elemMatch: { $eq: currentUserId } } },
      { users: { $elemMatch: { $eq: userId } } }
    ])
  return oneOnOneChat;
}

Approach 2

async findOneOnOneChat(currentUserId, userId) {
  const oneOnOneChat = await this.chatModel
    .find({
      isGroupChat: false,
    })
    .and([{ users: { $in: userId } }, { users: { $in: id } }])
  return oneOnOneChat;
}

So my question is what is the difference between two approach? Which approach is better? Or is there a better version can achieve what I want?


Solution

  • These are two different things.

    Use { users: { $in: userId } } when userId is an array, and you want the user value(s) to match one or more of the elements in userId. In this case user can be a single value or array of values, but userId must be an array. You can think of it as a loop on userId, that for each element in userId is searching for a match in user.

    Use { users: { $elemMatch: { $eq: userId } } } where users is an array and userId is a single value. You can think of it as a loop on users, that for each element in users is searching for a match that equals userId.