Estoy creando una especie de sistema de cola de trabajos en segundo plano con MongoDB como el almacén de datos. ¿Cómo puedo "escuchar" las inserciones de una colección MongoDB antes de generar trabajadores para procesar el trabajo? ¿Tengo que sondear cada pocos segundos para ver si hay algún cambio desde la última vez, o hay alguna forma en que mi script pueda esperar a que ocurran las inserciones? Este es un proyecto PHP en el que estoy trabajando, pero no dudes en responder en Ruby o en lenguaje agnóstico.
200
Respuestas:
Lo que estás pensando suena mucho a disparadores. MongoDB no tiene ningún soporte para los desencadenantes, sin embargo, algunas personas han "hecho lo suyo" usando algunos trucos. La clave aquí es el oplog.
Cuando ejecuta MongoDB en un conjunto de réplicas, todas las acciones de MongoDB se registran en un registro de operaciones (conocido como oplog). El oplog es básicamente una lista de las modificaciones realizadas a los datos. Los conjuntos de réplicas funcionan escuchando los cambios en este registro y luego aplicando los cambios localmente.
¿Te suena familiar?
No puedo detallar todo el proceso aquí, son varias páginas de documentación, pero las herramientas que necesita están disponibles.
Primero algunos relatos sobre el oplog - Descripción breve - Diseño de la
local
colección (que contiene el oplog)También querrás aprovechar los cursores disponibles . Estos le proporcionarán una forma de escuchar los cambios en lugar de sondearlos. Tenga en cuenta que la replicación utiliza cursores disponibles, por lo que esta es una característica compatible.
fuente
--replSet
opción y creará / completará eloplog
. Incluso sin la secundaria. Esta es definitivamente la única forma de "escuchar" los cambios en la base de datos.MongoDB tiene lo que se llama
capped collections
ytailable cursors
eso le permite a MongoDB enviar datos a los oyentes.A
capped collection
es esencialmente una colección que tiene un tamaño fijo y solo permite inserciones. Así es como se vería crear uno:Cursores Tago MongoDB ( publicación original de Jonathan H. Wage )
Rubí
PHP
Python (por Robert Stewart)
Perl (por Max )
Recursos adicionales:
Tutorial Ruby / Node.js que lo guía a través de la creación de una aplicación que escucha inserciones en una colección con tapa MongoDB.
Un artículo que habla sobre los cursores tailable con más detalle.
Ejemplos de PHP, Ruby, Python y Perl del uso de cursores disponibles.
fuente
Desde MongoDB 3.6 habrá una nueva API de notificaciones llamada Change Streams que puede usar para esto. Vea esta publicación de blog para un ejemplo . Ejemplo de ello:
fuente
Mira esto: Cambiar transmisiones
10 de enero de 2018 - Versión 3.6
* EDITAR: escribí un artículo sobre cómo hacer esto https://medium.com/riow/mongodb-data-collection-change-85b63d96ff76
https://docs.mongodb.com/v3.6/changeStreams/
Es nuevo en mongodb 3.6 https://docs.mongodb.com/manual/release-notes/3.6/ 2018/01/10
Para usar changeStreams, la base de datos debe ser un conjunto de replicación
Su base de datos será un " Standalone " por defecto.
El siguiente ejemplo es una aplicación práctica de cómo puede usar esto.
* Específicamente para Nodo.
Enlaces útiles:
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
fuente
La versión 3.6 de MongoDB ahora incluye flujos de cambio que es esencialmente una API en la parte superior del OpLog que permite casos de uso de tipo disparador / notificación.
Aquí hay un enlace a un ejemplo de Java: http://mongodb.github.io/mongo-java-driver/3.6/driver/tutorials/change-streams/
Un ejemplo de NodeJS podría verse así:
fuente
Alternativamente, puede utilizar el método estándar Mongo FindAndUpdate y, dentro de la devolución de llamada, activar un evento EventEmitter (en Nodo) cuando se ejecuta la devolución de llamada.
Cualquier otra parte de la aplicación o arquitectura que escuche este evento será notificada de la actualización, y cualquier información relevante enviada allí también. Esta es una forma realmente simple de lograr notificaciones de Mongo.
fuente
Muchas de estas respuestas solo le darán nuevos registros y no actualizaciones y / o son extremadamente ineficientes
La única forma confiable y eficaz de hacer esto es crear un cursor en la colección local db: oplog.rs para obtener TODOS los cambios en MongoDB y hacer lo que quiera. (¡MongoDB incluso hace esto internamente más o menos para admitir la replicación!)
Explicación de lo que contiene el oplog: https://www.compose.com/articles/the-mongodb-oplog-and-node-js/
Ejemplo de una biblioteca Node.js que proporciona una API sobre lo que está disponible para hacer con el oplog: https://github.com/cayasso/mongo-oplog
fuente
Hay un increíble conjunto de servicios disponibles llamado MongoDB Stitch . Mira en funciones de puntos / triggers . Tenga en cuenta que este es un servicio pago basado en la nube (AWS). En su caso, en una inserción, puede llamar a una función personalizada escrita en javascript.
fuente
Hay un ejemplo de Java en funcionamiento que se puede encontrar aquí .
La clave es OPCIONES DE CONSULTA aquí.
También puede cambiar la consulta de búsqueda, si no necesita cargar todos los datos cada vez.
fuente
En realidad, en lugar de mirar la salida, ¿por qué no se nota cuando se inserta algo nuevo utilizando el middleware proporcionado por el esquema de mangosta?
Puede detectar el evento de insertar un nuevo documento y hacer algo después de esta inserción
fuente
Después de 3.6 se permite usar la base de datos, los siguientes tipos de desencadenantes de la base de datos:
Inicie sesión en su cuenta Atlas, seleccione la
Triggers
interfaz y agregue un nuevo disparador:Expanda cada sección para más configuraciones o detalles.
fuente