212 votes

Comment écouter les modifications apportées à une collection MongoDB ?

Je suis en train de créer une sorte de système de file d'attente pour les travaux en arrière-plan avec MongoDB comme magasin de données. Comment puis-je "écouter" les insertions dans une collection MongoDB avant de créer des travailleurs pour traiter le travail ?

Dois-je interroger toutes les quelques secondes pour voir s'il y a des changements par rapport à la dernière fois, ou existe-t-il un moyen pour mon script d'attendre que les insertions se produisent ?

Il s'agit d'un projet PHP sur lequel je travaille, mais n'hésitez pas à répondre en Ruby ou dans un autre langage.

2 votes

Change Streams a été ajouté à MongoDB 3.6 pour répondre à votre scénario. docs.mongodb.com/manual/changeStreams De plus, si vous utilisez MongoDB Atlas, vous pouvez tirer parti des déclencheurs Stitch qui vous permettent d'exécuter des fonctions en réponse aux insertions/mises à jour/suppressions/etc. docs.mongodb.com/stitch/triggers/overview Il n'est plus nécessaire d'analyser l'oplog.

4voto

AlexW Points 1633

Vous pouvez également utiliser la méthode standard FindAndUpdate de Mongo et, dans le callback, déclencher un événement EventEmitter (dans Node) lorsque le callback est exécuté.

Toutes les autres parties de l'application ou de l'architecture qui écoutent cet événement seront informées de la mise à jour, et toutes les données pertinentes y seront également envoyées. C'est une façon très simple de réaliser des notifications à partir de Mongo.

3voto

John Culviner Points 4878

Beaucoup de ces réponses ne vous donneront que de nouveaux enregistrements et non des mises à jour et/ou sont extrêmement inefficaces.

La seule façon fiable et performante de le faire est de créer un curseur disponible sur la base de données locale : oplog.rs collection pour obtenir TOUS les changements vers MongoDB et en faire ce que vous voulez. (MongoDB fait même cela en interne plus ou moins pour supporter la réplication !)

Explication du contenu de l'oplog : https://www.compose.com/articles/the-mongodb-oplog-and-node-js/

Exemple de bibliothèque Node.js qui fournit une API autour de ce qu'il est possible de faire avec l'oplog : https://github.com/cayasso/mongo-oplog

3voto

Manish Jain Points 1505

Il existe un ensemble impressionnant de services appelés MongoDB Stitch . Consulter fonctions de couture/déclencheurs . Notez qu'il s'agit d'un système basé sur l'informatique dématérialisée. payé (AWS). Dans votre cas, lors d'une insertion, vous pourriez appeler une fonction personnalisée écrite en javascript.

enter image description here

1voto

Duong Nguyen Points 133

En fait, au lieu de surveiller la sortie, pourquoi ne pas être averti lorsque quelque chose de nouveau est inséré en utilisant un logiciel intermédiaire fourni par schéma de la mangouste

Vous pouvez capturer l'événement d'insertion d'un nouveau document et faire quelque chose après cette insertion.

0voto

Maleenc Points 401

Il existe un exemple fonctionnel en Java qui peut être consulté à l'adresse suivante aquí .

 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();

La clé est OPTIONS DE REQUÊTE ici.

Vous pouvez également modifier la requête de recherche si vous n'avez pas besoin de charger toutes les données à chaque fois.

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);

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X