How to listen for changes to a MongoDB collection?

后端 未结 11 1497
不思量自难忘°
不思量自难忘° 2020-11-22 06:08

I\'m creating a sort of background job queue system with MongoDB as the data store. How can I \"listen\" for inserts to a MongoDB collection before spawning workers to proce

相关标签:
11条回答
  • 2020-11-22 06:31

    Check out this: Change Streams

    January 10, 2018 - Release 3.6

    *EDIT: I wrote an article about how to do this https://medium.com/riow/mongodb-data-collection-change-85b63d96ff76

    https://docs.mongodb.com/v3.6/changeStreams/


    It's new in mongodb 3.6 https://docs.mongodb.com/manual/release-notes/3.6/ 2018/01/10

    $ mongod --version
    db version v3.6.2
    

    In order to use changeStreams the database must be a Replication Set

    More about Replication Sets: https://docs.mongodb.com/manual/replication/

    Your Database will be a "Standalone" by default.

    How to Convert a Standalone to a Replica Set: https://docs.mongodb.com/manual/tutorial/convert-standalone-to-replica-set/


    The following example is a practical application for how you might use this.
    * Specifically for Node.

    /* file.js */
    'use strict'
    
    
    module.exports = function (
        app,
        io,
        User // Collection Name
    ) {
        // SET WATCH ON COLLECTION 
        const changeStream = User.watch();  
    
        // Socket Connection  
        io.on('connection', function (socket) {
            console.log('Connection!');
    
            // USERS - Change
            changeStream.on('change', function(change) {
                console.log('COLLECTION CHANGED');
    
                User.find({}, (err, data) => {
                    if (err) throw err;
    
                    if (data) {
                        // RESEND ALL USERS
                        socket.emit('users', data);
                    }
                });
            });
        });
    };
    /* END - file.js */
    

    Useful links:
    https://docs.mongodb.com/manual/tutorial/convert-standalone-to-replica-set
    https://docs.mongodb.com/manual/tutorial/change-streams-example

    https://docs.mongodb.com/v3.6/tutorial/change-streams-example
    http://plusnconsulting.com/post/MongoDB-Change-Streams

    0 讨论(0)
  • 2020-11-22 06:35

    There is an working java example which can be found here.

     MongoClient mongoClient = new MongoClient();
        DBCollection coll = mongoClient.getDatabase("local").getCollection("oplog.rs");
    
        DBCursor cur = coll.find().sort(BasicDBObjectBuilder.start("$natural", 1).get())
                .addOption(Bytes.QUERYOPTION_TAILABLE | Bytes.QUERYOPTION_AWAITDATA);
    
        System.out.println("== open cursor ==");
    
        Runnable task = () -> {
            System.out.println("\tWaiting for events");
            while (cur.hasNext()) {
                DBObject obj = cur.next();
                System.out.println( obj );
    
            }
        };
        new Thread(task).start();
    

    The key is QUERY OPTIONS given here.

    Also you can change find query, if you don't need to load all the data every time.

    BasicDBObject query= new BasicDBObject();
    query.put("ts", new BasicDBObject("$gt", new BsonTimestamp(1471952088, 1))); //timestamp is within some range
    query.put("op", "i"); //Only insert operation
    
    DBCursor cur = coll.find(query).sort(BasicDBObjectBuilder.start("$natural", 1).get())
    .addOption(Bytes.QUERYOPTION_TAILABLE | Bytes.QUERYOPTION_AWAITDATA);
    
    0 讨论(0)
  • 2020-11-22 06:40

    Actually, instead of watching output, why you dont get notice when something new is inserted by using middle-ware that was provided by mongoose schema

    You can catch the event of insert a new document and do something after this insertion done

    0 讨论(0)
  • 2020-11-22 06:44

    There is an awesome set of services available called MongoDB Stitch. Look into stitch functions/triggers. Note this is a cloud-based paid service (AWS). In your case, on an insert, you could call a custom function written in javascript.

    0 讨论(0)
  • 2020-11-22 06:45

    After 3.6 one is allowed to use database the following database triggers types:

    • event-driven triggers - useful to update related documents automatically, notify downstream services, propagate data to support mixed workloads, data integrity & auditing
    • scheduled triggers - useful for scheduled data retrieval, propagation, archival and analytics workloads

    Log into your Atlas account and select Triggers interface and add new trigger:

    Expand each section for more settings or details.

    0 讨论(0)
  • 2020-11-22 06:49

    Alternatively, you could use the standard Mongo FindAndUpdate method, and within the callback, fire an EventEmitter event (in Node) when the callback is run.

    Any other parts of the application or architecture listening to this event will be notified of the update, and any relevant data sent there also. This is a really simple way to achieve notifications from Mongo.

    0 讨论(0)
提交回复
热议问题