Estou criando um tipo de sistema de fila de tarefas em segundo plano com o MongoDB como armazenamento de dados. Como posso "escutar" inserções em uma coleção do MongoDB antes de gerar trabalhadores para processar o trabalho? Preciso pesquisar a cada poucos segundos para ver se há alguma alteração da última vez, ou existe uma maneira de meu script aguardar a inserção de inserções? Este é um projeto PHP em que estou trabalhando, mas sinta-se à vontade para responder em Ruby ou em linguagem independente.
200
Respostas:
O que você está pensando soa muito como gatilhos. O MongoDB não tem suporte para gatilhos, no entanto, algumas pessoas "criaram seus próprios" usando alguns truques. A chave aqui é o oplog.
Quando você executa o MongoDB em um conjunto de réplicas, todas as ações do MongoDB são registradas em um log de operações (conhecido como oplog). O oplog é basicamente apenas uma lista em execução das modificações feitas nos dados. Réplicas Define a função ouvindo as alterações neste oplog e aplicando as alterações localmente.
Isso soa familiar?
Não posso detalhar todo o processo aqui, são várias páginas de documentação, mas as ferramentas necessárias estão disponíveis.
Primeiro, alguns artigos escritos no oplog - Breve descrição - Layout da
local
coleção (que contém o oplog)Você também deseja aproveitar os cursores disponíveis . Isso fornecerá uma maneira de ouvir as alterações, em vez de pesquisar por elas. Observe que a replicação usa cursores disponíveis, portanto, esse é um recurso suportado.
fonte
--replSet
opção e ele criará / preencherá o arquivooplog
. Mesmo sem o secundário. Essa é definitivamente a única maneira de "ouvir" as alterações no banco de dados.O MongoDB possui o que é chamado
capped collections
etailable cursors
isso permite que o MongoDB envie dados para os ouvintes.A
capped collection
é essencialmente uma coleção de tamanho fixo e permite apenas inserções. Aqui está como seria criar um:Cursores disponíveis do MongoDB ( postagem original de Jonathan H. Wage )
Rubi
PHP
Python (de Robert Stewart)
Perl (de Max )
Recursos adicionais:
Tutorial do Ruby / Node.js, que orienta você na criação de um aplicativo que ouve inserções em uma coleção limitada do MongoDB.
Um artigo falando sobre cursores disponíveis em mais detalhes.
Exemplos de PHP, Ruby, Python e Perl do uso de cursores disponíveis.
fonte
Desde o MongoDB 3.6, haverá uma nova API de notificações chamada Change Streams, que você pode usar para isso. Veja esta postagem no blog para obter um exemplo . Exemplo disso:
fonte
Confira isto: Change Streams
10 de janeiro de 2018 - Versão 3.6
* EDIT: escrevi um artigo sobre como fazer isso https://medium.com/riow/mongodb-data-collection-change-85b63d96ff76
https://docs.mongodb.com/v3.6/changeStreams/
É novo no mongodb 3.6 https://docs.mongodb.com/manual/release-notes/3.6/ 2018/01/10
Para usar o changeStreams, o banco de dados deve ser um Conjunto de Replicação
Seu banco de dados será " autônomo " por padrão.
O exemplo a seguir é um aplicativo prático de como você pode usar isso.
* Especificamente para Nó.
Links úteis:
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
fonte
O MongoDB versão 3.6 agora inclui fluxos de alterações, que são essencialmente uma API no topo do OpLog, permitindo casos de uso semelhantes a acionamentos / notificações.
Aqui está um link para um exemplo de Java: http://mongodb.github.io/mongo-java-driver/3.6/driver/tutorials/change-streams/
Um exemplo do NodeJS pode ser algo como:
fonte
Como alternativa, você pode usar o método Mongo FindAndUpdate padrão e, dentro do retorno de chamada, acionar um evento EventEmitter (no Node) quando o retorno de chamada é executado.
Quaisquer outras partes do aplicativo ou arquitetura que estiverem ouvindo esse evento serão notificadas sobre a atualização e quaisquer dados relevantes enviados para lá também. Essa é uma maneira muito simples de obter notificações do Mongo.
fonte
Muitas dessas respostas fornecerão apenas novos registros e não atualizações e / ou são extremamente ineficientes
A única maneira confiável e eficiente de fazer isso é criar um cursor disponível na coleção db: oplog.rs local para obter TODAS as alterações no MongoDB e fazer o que você desejar. (O MongoDB ainda faz isso internamente mais ou menos para oferecer suporte à replicação!)
Explicação do conteúdo do oplog: https://www.compose.com/articles/the-mongodb-oplog-and-node-js/
Exemplo de uma biblioteca Node.js que fornece uma API em torno do que está disponível para ser feito com o oplog: https://github.com/cayasso/mongo-oplog
fonte
Existe um impressionante conjunto de serviços disponíveis chamado MongoDB Stitch . Observe as funções / gatilhos do ponto . Observe que este é um serviço pago baseado na nuvem (AWS). No seu caso, em uma inserção, você pode chamar uma função personalizada escrita em javascript.
fonte
Há um exemplo de java que pode ser encontrado aqui .
A chave é QUERY OPTIONS fornecida aqui.
Além disso, você pode alterar a consulta de busca, se não precisar carregar todos os dados todas as vezes.
fonte
Na verdade, em vez de assistir à saída, por que você não recebe aviso quando algo novo é inserido usando o middleware que foi fornecido pelo esquema de mangusto
Você pode capturar o evento de inserir um novo documento e fazer alguma coisa após essa inserção
fonte
Após o 3.6, é permitido usar o banco de dados, os seguintes tipos de gatilhos de banco de dados:
Entre na sua conta Atlas, selecione a
Triggers
interface e adicione um novo gatilho:Expanda cada seção para obter mais configurações ou detalhes.
fonte