skip to Main Content

I am creating a chat application using nodejs and mongodb. I need need help retrieving messages between two users. The challenge am facing is I don’t know how to filter the chats between two users since a user can be a sender or a recipient.

const messageSchema = new mongoose.Schema({
    content:{type:String, required:true},
    fromUser:{type:mongoose.Schema.Types.ObjectId, ref:'User'},
    toUser:{type:mongoose.Schema.Types.ObjectId, ref:'User'},
    messageRead:{type:Boolean, default:false}
},{
    timestamps:true
})

2

Answers


  1. You can achieve this using $and and $in operators in a match aggregation like this:

    db.collection.aggregate([
      {
        $match: {
          $and: [
            {
              fromUser: {
                $in: [
                  "user1",
                  "user2"
                ]
              }
            },
            {
              toUser: {
                $in: [
                  "user1",
                  "user2"
                ]
              }
            }
          ]
        }
      }
    ])
    

    In mongoose if your model is MessageModel your query must be like this:

    const messages = await MessageModel.aggregate([...])
    

    Mongodb Playground

    You may need to convert user1 and user2 to ObjectId like this:

          fromUser: {
            $in: [
              new mongoose.Types.ObjectId('user1'),
              new mongoose.Types.ObjectId('user2')
            ]
          }
    
    Login or Signup to reply.
  2. I recommend getting the data exactly as you want it. The accepted answer (using $in operator) is not as performant as an exact match, and aggregation is a bit overkill for such a basic query.

    const userA = new ObjectId('user_a_id');
    const userB = new ObjectId('user_b_id');
    const messages = await MessageModel.find({
      $or: [
        { fromUser: userA, toUser: userB },
        { fromUser: userB, toUser: userA },
      ]
    }).exec();
    
    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search