Ich erstelle eine Art Hintergrund-Job-Warteschlangensystem mit MongoDB als Datenspeicher. Wie kann ich auf Einfügungen in eine MongoDB-Sammlung "lauschen", bevor ich Arbeiter zur Bearbeitung des Jobs hervorbringe? Muss ich alle paar Sekunden abfragen, um festzustellen, ob sich Änderungen gegenüber dem letzten Mal ergeben haben, oder kann mein Skript auf das Einfügen warten? Dies ist ein PHP-Projekt, an dem ich arbeite, aber ich kann gerne in Ruby oder sprachunabhängig antworten.
200
Antworten:
Was Sie denken, klingt sehr nach Auslösern. MongoDB hat keine Unterstützung für Trigger, jedoch haben einige Leute mit einigen Tricks "ihre eigenen gewürfelt". Der Schlüssel hier ist das Oplog.
Wenn Sie MongoDB in einem Replikatsatz ausführen, werden alle MongoDB-Aktionen in einem Betriebsprotokoll (bekannt als Oplog) protokolliert. Das Oplog ist im Grunde nur eine laufende Liste der an den Daten vorgenommenen Änderungen. Replikate Legt die Funktion fest, indem Änderungen in diesem Oplog abgehört und die Änderungen dann lokal angewendet werden.
Kommt Ihnen das bekannt vor?
Ich kann den gesamten Prozess hier nicht detaillieren, es sind mehrere Seiten Dokumentation, aber die Tools, die Sie benötigen, sind verfügbar.
Zuerst einige Beschreibungen zum Oplog - Kurzbeschreibung - Layout der
local
Sammlung (die das Oplog enthält)Sie möchten auch schwanzfähige Cursor nutzen . Diese bieten Ihnen die Möglichkeit, auf Änderungen zu warten, anstatt sie abzufragen. Beachten Sie, dass bei der Replikation anpassbare Cursor verwendet werden. Dies ist also eine unterstützte Funktion.
quelle
--replSet
Option starten und er erstellt / füllt denoplog
. Auch ohne die sekundäre. Dies ist definitiv die einzige Möglichkeit, Änderungen in der Datenbank "abzuhören".MongoDB hat das, was so genannt wird,
capped collections
undtailable cursors
das ermöglicht es MongoDB, Daten an die Listener zu senden.A
capped collection
ist im Wesentlichen eine Sammlung mit fester Größe, die nur Einfügungen zulässt. So würde es aussehen, eine zu erstellen:MongoDB Tailable Cursor ( Originalbeitrag von Jonathan H. Wage )
Rubin
PHP
Python (von Robert Stewart)
Perl (von Max )
Zusätzliche Ressourcen:
Ruby / Node.js Tutorial, das Sie durch die Erstellung einer Anwendung führt, die Einfügungen in eine MongoDB-gekappte Sammlung abhört.
Ein Artikel, der ausführlicher über schwanzfähige Cursor spricht.
PHP-, Ruby-, Python- und Perl-Beispiele für die Verwendung von Tailable-Cursorn.
quelle
Seit MongoDB 3.6 wird es eine neue Benachrichtigungs-API namens Change Streams geben, die Sie dafür verwenden können. In diesem Blogbeitrag finden Sie ein Beispiel . Beispiel daraus:
quelle
Überprüfen Sie dies: Streams ändern
10. Januar 2018 - Release 3.6
* BEARBEITEN: Ich habe einen Artikel darüber geschrieben, wie das geht https://medium.com/riow/mongodb-data-collection-change-85b63d96ff76
https://docs.mongodb.com/v3.6/changeStreams/
Es ist neu in Mongodb 3.6 https://docs.mongodb.com/manual/release-notes/3.6/ 2018/01/10
Um changeStreams verwenden zu können, muss die Datenbank ein Replikationssatz sein
Ihre Datenbank ist standardmäßig " Standalone ".
Das folgende Beispiel ist eine praktische Anwendung, wie Sie dies verwenden können.
* Speziell für Node.
Nützliche 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
quelle
MongoDB Version 3.6 enthält jetzt Änderungsströme, die im Wesentlichen eine API über dem OpLog sind und Trigger- / Benachrichtigungs-ähnliche Anwendungsfälle ermöglichen.
Hier ist ein Link zu einem Java-Beispiel: http://mongodb.github.io/mongo-java-driver/3.6/driver/tutorials/change-streams/
Ein NodeJS-Beispiel könnte ungefähr so aussehen:
quelle
Alternativ können Sie die Standardmethode Mongo FindAndUpdate verwenden und innerhalb des Rückrufs ein EventEmitter-Ereignis (in Node) auslösen, wenn der Rückruf ausgeführt wird.
Alle anderen Teile der Anwendung oder Architektur, die dieses Ereignis abhören, werden über das Update informiert, und alle relevanten Daten werden ebenfalls dorthin gesendet. Dies ist eine sehr einfache Möglichkeit, Benachrichtigungen von Mongo zu erhalten.
quelle
Viele dieser Antworten geben Ihnen nur neue Datensätze und keine Aktualisierungen und / oder sind äußerst ineffizient
Die einzige zuverlässige und performante Möglichkeit, dies zu tun, besteht darin, einen anpassbaren Cursor auf der lokalen Sammlung db: oplog.rs zu erstellen, um ALLE Änderungen an MongoDB zu erhalten und damit zu tun, was Sie wollen. (MongoDB tut dies sogar mehr oder weniger intern, um die Replikation zu unterstützen!)
Erklärung, was das Oplog enthält: https://www.compose.com/articles/the-mongodb-oplog-and-node-js/
Beispiel für eine Node.js-Bibliothek, die eine API für die verfügbaren Funktionen des Oplogs bereitstellt: https://github.com/cayasso/mongo-oplog
quelle
Es gibt eine fantastische Reihe von Diensten namens MongoDB Stitch . Schauen Sie sich Stichfunktionen / Trigger an . Beachten Sie, dass dies ein Cloud-basierter kostenpflichtiger Dienst (AWS) ist. In Ihrem Fall können Sie auf einer Einfügung eine benutzerdefinierte Funktion aufrufen, die in Javascript geschrieben ist.
quelle
Es gibt ein funktionierendes Java-Beispiel, das hier zu finden ist .
Der Schlüssel sind die hier angegebenen Abfrageoptionen .
Sie können auch die Suchabfrage ändern, wenn Sie nicht jedes Mal alle Daten laden müssen.
quelle
Anstatt die Ausgabe zu sehen, werden Sie nicht bemerkt, wenn etwas Neues eingefügt wird, indem Sie Middleware verwenden, die vom Mungo-Schema bereitgestellt wurde
Sie können den Fall des Einfügens eines neuen Dokuments abfangen und nach dem Einfügen etwas unternehmen
quelle
Nach 3.6 darf man Datenbank die folgenden Datenbank-Trigger-Typen verwenden:
Melden Sie sich bei Ihrem Atlas-Konto an, wählen Sie die
Triggers
Benutzeroberfläche aus und fügen Sie einen neuen Auslöser hinzu:Erweitern Sie jeden Abschnitt für weitere Einstellungen oder Details.
quelle