sql >> Database teknologi >  >> NoSQL >> MongoDB

MongoDB:er det muligt at fange TTL-begivenheder med Change Stream for at efterligne en skemalægger (cronjob)?

Jeg var i stand til at bruge Change Streams og TTL til at efterligne en cronjob. Jeg har udgivet et indlæg, der forklarer, hvad jeg gjorde i detaljer og gav kredit på:https://www. patreon.com/posts/17697287

Men dybest set, når jeg har brug for at planlægge en "begivenhed" for et dokument, når jeg opretter dokumentet, opretter jeg også et begivenhedsdokument parallelt. Dette hændelsesdokument vil have det samme id som det første dokument som _id.

Også for dette begivenhedsdokument vil jeg indstille en TTL.

Når TTL udløber, vil jeg fange dens "slet"-ændring med Change Streams. Og så bruger jeg ændringens documentKey (da det er det samme id som det dokument, jeg vil udløse) til at finde måldokumentet i den første samling og gøre hvad jeg vil med dokumentet.

Jeg bruger Node.js med Express og Mongoose for at få adgang til MongoDB. Her er den relevante del, der skal tilføjes i 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');
        });
    });

}

Og her er koden til 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. Sådan konfigureres Redis i brugerdefineret navneområde som cache og MQ på ServiceStack-webapplikation ved hjælp af Structuremap

  2. Sådan styres projektionsdefinitionen i MongoDb ved hjælp af C#

  3. Oprettelse af fil i GridFs (MongoDb)

  4. Hvordan fjerner man objekt under hensyntagen til referencer i Mongoose Node.js?