Search code examples
javascriptnode.jsmongodbexpressmongoose

Mongoose watch() is not triggering the insert event


The current version of mongodb is 4.4.6 and Data.watch() method doesn't get trigger. I checked with the changeStream and the connection created is fine and there is not problem with it. The stream is also properly created. I tried adding the data from both through my api and mongodb client.

const express = require('express');
const app = express();
const http = require('http').Server(app);
const io = require('socket.io')(http);
const mongoose = require('mongoose');
app.use(express.json())

// Connect to MongoDB using Mongoose
mongoose.connect('mongodb://localhost:27017/socketdb');


// Define a schema for the data
const dataSchema = new mongoose.Schema({
  name: String,
  age: Number,
  timestamp: { type: Date, default: Date.now }
});

// Create a model for the data
const Data = mongoose.model('Data', dataSchema);

// Connect to Socket.io
io.on('connection', function (socket) {
  console.log('A user connected');
  Data.find({}).then(
    data => socket.emit('allData', data)
  ).catch(err => console.log(err))


  // Watch for changes in the MongoDB collection
  if (mongoose.connection.readyState !== 1) {
    console.log('Mongoose is not connected');
  }
  let pipeline = [
    {
      $match: {
        operationType: 'insert'
      }
    }
  ];
  
  let changeStream = Data.watch(pipeline)
  .on('change', data => console.log(data))

  console.log(changeStream)
  changeStream.on('change', function (change) {
    console.log('Change stream event:', change);

    // Send the new or updated data to the client
    if (change.operationType === 'insert') {
      socket.emit('newData', change.fullDocument);
      console.log(change.fullDocument)
    } else if (change.operationType === 'update') {
      Data.findById(change.documentKey._id, function (err, data) {
        if (err) throw err;
        socket.emit('newData', data);
      });
    }
  });

  socket.on('disconnect', function () {
    console.log('A user disconnected');
    // changeStream.close();
  });
});

// Serve the HTML page
app.get('/', function (req, res) {
  res.sendFile(__dirname + '/index.html');
});

app.post('/adddata', (req, res) => {
  let d = new Data({
    name: req.body.name,
    age: req.body.age
  })
  d.save().then(() => {
    res.send("Data Added")
  }).catch((err) => {
    res.send("ERR")
  })
  Data.watch(pipeline).on('change', data => console.log('inside the add',data))

})

// Start the server
http.listen(3000, function () {
  console.log('Listening on port 3000');
});

Here changeStream.on('change') never gets trigger even if the data is added. I am following up the official documentation from: Official Documentation


Solution

  • This problem is caused because you are using local database ,Use a shared cluster then it will work.

    Note:that you must be connected to a MongoDB replica set or sharded cluster to use change streams. Mongoose Documentation

    You can create one by visiting MongoDB Atlas.MongoDB Atlas

    1. Create account on Atlas
    2. Create a shared Cluster( You can make one for free ).
    3. Connect to cluster from your application.How to connect to your cluster