Search code examples
node.jsmongodbsocket.iochangestream

While using Change Stream in MongoDB with Socket.io, the on 'change' is getting triggered multiple times


I have been trying to catch any realtime update or insert in the mongodb and using socket.io to change information accordingly on the next page. But whenever there is any update in the database, the on 'change' stream is getting triggered multiple times. I assume that this might also be the reason behind the socket acting slow and with delay. Any kind of help is really appreciated.

const Order = new mongoose.model("Order", orderSchema);

io.on('connection', function(socket){
    console.log(socket.id);
    Order.watch([{ $match: {operationType: {$in: ['insert']}}}]).
    on('change', data => {
        console.log('Insert action triggered'); //getting triggered thrice
        console.log(new Date(), data.fullDocument);
        socket.emit("changes", data.fullDocument); 

    });
    Order.watch([{ $match: {operationType: {$in: ['update']}}}]).
    on('change', data => {
        console.log('Update action triggered'); //getting triggered thrice
        console.log(new Date(), data.updateDescription.updatedFields);
        socket.emit("customer", data);
    });

});

Solution

  • You need to put your mongodb changeStreams outside the io.on('connection') and use io.emit() instead of socket.emit()

    Here is the code for example:

    const Order = new mongoose.model("Order", orderSchema);
    
    io.on('connection', function(socket){
        console.log(socket.id);
    
        socket.on('disconnect', (reason) => {
            console.log(reason);
        });
    });
    
    Order.watch([{ $match: {operationType: {$in: ['insert']}}}]).
    on('change', data => {
        console.log('Insert action triggered');
        console.log(new Date(), data.fullDocument);
        io.emit("changes", data.fullDocument); 
    
    });
    Order.watch([{ $match: {operationType: {$in: ['update']}}}]).
    on('change', data => {
        console.log('Update action triggered');
        console.log(new Date(), data.updateDescription.updatedFields);
        io.emit("customer", data);
    });