Skip to content
Advertisement

How do I get the same parent result regardless of the order of children being queried? (One to Many)

I’m building a chat with private rooms. What I’m trying to do is find a room that two users belong too. If there isn’t one create one.

Chat Schema

export const ChatSchema = new mongoose.Schema({
    participants: [{
        type: mongoose.Schema.Types.ObjectId,
        ref: "User"
    }],
    created_at: { type: Date, default: Date.now },
});

Query

async findChatBetweenUsers(participantOneId, participantTwoId) {
   return await (await this.chatModel.findOne( { participants: [participantOneId, participantTwoId] } )).populate('participants');
}

Controller

async onJoinRoom(socket: Socket, reciever) {
    const authUser: User = await this.authUser(socket);
    const recievingUser: User = await this.userService.findOne(reciever.username);
    const chat = await this.chatService.findChatBetweenUsers(authUser, recievingUser);

    //Create new chat if doesn't exist
    if(Object.entries(chat).length === 0){
      const newChat = await this.chatService.create(authUser, recievingUser);

      return;
    }

    console.log(chat)
  
}

The problem I’m having

The order of the auth and receiver changes depending who is logged in and produces a different query result for chat. For example:

Example One

const chat = await this.chatService.findChatBetweenUsers('KylesId', 'ChrisId');

Output

"chat" : {
    "_id": 'chatOneId',
    "participants": ['KylesId', 'ChrisId']
}

Example Two

const chat = await this.chatService.findChatBetweenUsers('ChrisId','KylesId');

Output

"chat" : {
    "_id": 'chatTwoId',
    "participants": ['ChrisId', 'KylesId']
}

How do I get the same result despite the order of participants being queried?

Advertisement

Answer

If, instead, you wish to find an array that contains both the elements “red” and “blank”, without regard to order or other elements in the array, use the $all operator:

this.chatModel.find({
  participants: {$all: [ObjectId('61ce732e33c7e8a9ad80e151'), ObjectId('61ccf3251b9ba5c8a6ecf2a3')]}
});
Advertisement