sql >> Database >  >> NoSQL >> MongoDB

MongoDB:is het mogelijk om TTL-gebeurtenissen vast te leggen met Change Stream om een ​​planner (cronjob) te emuleren?

Ik kon Change Streams en TTL gebruiken om een ​​cronjob te emuleren. Ik heb een bericht gepubliceerd waarin ik gedetailleerd uitleg wat ik heb gedaan en credits heb gegeven op:https://www. patreon.com/posts/17697287

Maar in principe, wanneer ik een "gebeurtenis" voor een document moet plannen, wanneer ik het document aan het maken ben, maak ik tegelijkertijd ook een gebeurtenisdocument. Dit gebeurtenisdocument heeft als _id dezelfde id als het eerste document.

Ook zal ik voor dit evenementdocument een TTL instellen.

Wanneer de TTL verloopt, zal ik de "verwijder"-wijziging vastleggen met Change Streams. En dan gebruik ik de documentKey van de wijziging (omdat het dezelfde id is als het document dat ik wil activeren) om het doeldocument in de eerste verzameling te vinden en alles te doen wat ik wil met het document.

Ik gebruik Node.js met Express en Mongoose om toegang te krijgen tot MongoDB.Hier is het relevante deel dat moet worden toegevoegd in de App.js:

const { ReplSet } = require('mongodb-topology-manager');

run().catch(error => console.error(error));

async function run() {
    console.log(new Date(), 'start');
    const bind_ip = 'localhost';
    // Starts a 3-node replica set on ports 31000, 31001, 31002, replica set
    // name is "rs0".
    const replSet = new ReplSet('mongod', [
        { options: { port: 31000, dbpath: `${__dirname}/data/db/31000`, bind_ip } },
        { options: { port: 31001, dbpath: `${__dirname}/data/db/31001`, bind_ip } },
        { options: { port: 31002, dbpath: `${__dirname}/data/db/31002`, bind_ip } }
    ], { replSet: 'rs0' });

    // Initialize the replica set
    await replSet.purge();
    await replSet.start();
    console.log(new Date(), 'Replica set started...');

    // Connect to the replica set
    const uri = 'mongodb://localhost:31000,localhost:31001,localhost:31002/' + 'test?replicaSet=rs0';
    await mongoose.connect(uri);
    var db = mongoose.connection;
    db.on('error', console.error.bind(console, 'connection error:'));
    db.once('open', function () {
        console.log("Connected correctly to server");
    });

    // To work around "MongoError: cannot open $changeStream for non-existent database: test" for this example
    await mongoose.connection.createCollection('test');

    // *** we will add our scheduler here *** //

    var Item = require('./models/item');
    var ItemExpiredEvent = require('./models/scheduledWithin');

    let deleteOps = {
      $match: {
          operationType: "delete" 
      }
    };

    ItemExpiredEvent.watch([deleteOps]).
        on('change', data => {
            // *** treat the event here *** //
            console.log(new Date(), data.documentKey);
            Item.findById(data.documentKey, function(err, item) {
                console.log(item);
            });
        });

    // The TTL set in ItemExpiredEvent will trigger the change stream handler above
    console.log(new Date(), 'Inserting item');
    Item.create({foo:"foo", bar: "bar"}, function(err, cupom) {
        ItemExpiredEvent.create({_id : item._id}, function(err, event) {
            if (err) console.log("error: " + err);
            console.log('event inserted');
        });
    });

}

En hier is de code voor model/ScheduledWithin:

var mongoose = require('mongoose');
var Schema = mongoose.Schema;

var ScheduledWithin = new Schema({
    _id: mongoose.Schema.Types.ObjectId,
}, {timestamps: true}); 
// timestamps: true will automatically create a "createdAt" Date field

ScheduledWithin.index({createdAt: 1}, {expireAfterSeconds: 90});

module.exports = mongoose.model('ScheduledWithin', ScheduledWithin);


  1. Hoe direct een geneste veld opvragen zonder het bovenliggende veld op te geven?

  2. Geheugenlek in MongoDB-cursor (OutOfMemory)?

  3. MongoDB:proberen om Long uit JSON te lezen, veroorzaakt java.lang.Integer kan niet worden gecast naar java.lang.Long

  4. Ruby groep hashes op waarde van sleutel