Explore o novo chatbot do Developer Center! O MongoDB AI chatbot pode ser acessado na parte superior da sua navegação para responder a todas as suas perguntas sobre o MongoDB .

Learn why MongoDB was selected as a leader in the 2024 Gartner® Magic Quadrant™
Desenvolvedor do MongoDB
Central de desenvolvedor do MongoDBchevron-right
Produtoschevron-right
Atlaschevron-right

Crie um site de boletim informativo com a plataforma de dados MongoDB

Dominic Wellington9 min read • Published Jan 19, 2022 • Updated Sep 09, 2024
AtlasJavaScript
Ícone do FacebookÍcone do Twitterícone do linkedin
Avalie esse Artigo
star-empty
star-empty
star-empty
star-empty
star-empty
Alguns recursos mencionados abaixo serão descontinuados em 30, 2025 de setembro. Saiba mais.
Observação: este artigo discute o Stitch. Stitch agora é MongoDB Realm. Todas as mesmas funcionalidades e funcionalidades, agora com um novo nome. Saiba mais aqui. Atualizaremos este artigo no devido tempo.
"Isto será simples", ocorreu. "Quão difícil isso pode ser?" Eu disse para mim mesmo, imprudentemente.
Registro de arranhão
Congelar quadro
Sim, desde logo. Você provavelmente está se perguntado como parei nessa situação.
Era uma vez uma pequena empresa, e essa pequena empresa tinha um boletim informativo interno para informar as pessoas sobre o que estava acontecendo. Como a empresa era pequena e todos estavam ocupados, optou-se pela abordagem mais simples e mínima, ou seja, um Google Doc que qualquer pessoa da equipe de Marketing pudesse atualizar quando houvesse notícias relevantes. Este sistema funcionou bem.
À medida que a empresa cresce, um Google Doc se tornou muitos Google Docs, e foi adicionado um e-mail automatizado que era enviado uma vez por semana para lembrar as pessoas de consultar os Docs. Agora, as coisas não eram tão simples. Talvez os Docs tenham sido atualizados, e talvez não, porque nem sempre ficou claro quem era o proprietário do que. As pessoas que receberam o e-mail apenas viam links para os Docs, sem indicação de se havia algo novo ou bom neles e, depois de um tempo, pararam de clicar, ou apenas o fizeram ocasionalmente. A pessoa que estava enviando os e-mails conseguiu um novo trabalho e pediu que alguém assumisse a administração da newsletter.
É aqui que eu entro. Sim, não consegui me esconder quando o chefe veio pedir voluntários.
Dei uma olhada no sistema existente e sabia que ele não poderia continuar como estava — então, é claro, também comecei a procurar idiotas, MEAN, voluntários. Infelizmente, não consegui encontrar ninguém que quisesse assumir a lavagem dessa cerca em particular, então comecei a tentar descobrir o quão difícil seria montar meu próprio sistema automatizado de lavagem de cercas para executar o back-end do boletim informativo.
Rapidamente eu tinha meu produto mínimo desejável, graças ao MongoDB Atlas e Stitch. E a melhor parte? A coisa toda se encaixa na camada grátis de ambos. Você pode obter sua própria instância gratuita para sempre aqui, apenas fornecendo seu endereço de e-mail. E, se você me pedir com jeito, posso até jogar alguns créditos grátis para que você experimente alguns dos recursos pagos também.
Se você ainda não configurou seu cluster gratuito no MongoDB Atlas, agora é um ótimo momento para fazer isso. Você tem todas as instruções nesta publicação no blog.
Captura de tela do Above The Fold

Modelagem de dados: o documento

O primeiro Obstáculo deste projeto foi desaprenddo de mau hábitat de relacionamento. No mundo do relational database, um boletim informativo como esse provavelmente usaria vários JOINs:
  • Uma tabela de problemas
  • Contendo referências a uma tabela de notícias
  • Contendo referências a outras tabelas de tópicos, autores
No mundo orientado a documentos, não fizemos dessa forma. Em vez disso, defini um formato de documento simples:
1{
2 _id: 5e715b2099e27fa8539274ea,
3 section: "events",
4 itemTitle: "[Webinar] Building FHIR Applications with MongoDB, April 14th",
5 itemText: "MongoDB and FHIR both natively support the JSON format, the standard e...",
6 itemLink: "https://www.mongodb.com/webinar/building-fhir-applications-with-mongod...",
7 tags: ["fhir", "healthcare", "webinar"],
8 createdDate: 2020-03-17T23:01:20.038+00:00
9 submitter: "marketing.genius@mongodb.com",
10 updates: [],
11 published: "true",
12 publishedDate: 2020-03-30T07:10:06.955+00:00
13 email: "true"
14}
Essa estrutura deve ser bastante auto-explicativa. Cada item de notícias tem:
  • Um título
  • Texto descritivo
  • Um link para mais informações
  • Uma ou mais tags de tópico
  • Além de alguns campos utilitários para fazer coisas como rastrear edições
Cada item faz parte de uma seção e pode ser publicado simplesmente na Web ou também por e-mail. Não quero enviar spam aos leitores com tudo, por isso o e-mail é selecionado; somente os itens com email: true Go para o e-mail, enquanto todos os outros são exibidos no site, mas não nas caixas de entrada dos leitores.
Um item a destacar é a array de atualizações, que está vazia neste exemplo específico. Esse campo foi adicionado posteriormente ao formato, pois percebi, quando criei a funcionalidade de edição, que seria bom rastrear quem fez as edições e quando. A flexibilidade do document model fazia com que eu pudesse simplesmente adicionar esse campo sem causar nenhuma alteração em cascata em outras partes do código, ou mesmo em documentos que já tinham sido criados no banco de dados.
Tanto para o final do banco de dados. Agora precisamos de algo para ler os documentos e fazer algo útil com eles.
Optei pelo Stitch, que junto com o banco de dados Atlas é outra parte da plataforma MongoDB Cloud. De acordo com a direção geral do projeto, o Stitch torna a minha vida superfácil ao lidar com coisas como autenticação, regras de acesso, queries do MongoDB, serviços e funções. É muito mais do que apenas um local conveniente para armazenar arquivos; usando o Stitch, deixe-me escrever o código em JavaScript, me forneceu um lugar fácil para hospedar a lógica do aplicativo e se conecta ao banco de dados MongoDB Atlas com uma única linha de código:
1client = stitch.Stitch.initializeDefaultAppClient(APP_ID);
APP_ID é, é claro, o ID do meu aplicativo privado, que não vamos incluir aqui! Todo o código do aplicativo pode ser encontrado em meu repositório pessoal do Github; quase todas as funcionalidades (e todo o código dos exemplos abaixo) estão em um único arquivo Javascript.

Lendo documentos

O boletim informativo é enviado em e-mail HTML e tem um site complementar, então meu aplicativo Stitch monta seções Dom em Javascript para exibir o boletim informativo. Não Go explicar todo o processo, mas cada etapa é mais ou menos assim:
1let itemTitleContainer = document.createElement("div");
2itemTitleContainer.setAttribute("class", "news-item-title");
3itemContainer.append(itemTitleContainer);
4
5let itemTitle = document.createElement("p");
6itemTitle.textContent = currentNewsItem.itemTitle;
7itemTitleContainer.append(itemTitle);
Essa lógica mostra o benefício do modelo de objeto de documento no MongoDB. currentNewsItem é um objeto em JavaScript que mapeia exatamente para o documento no MongoDB, e posso acessar os campos do documento simplesmente pelo nome, como em currentNewsItem.itemTitle. Não preciso criar uma representação de objeto totalmente separada em meu código e preenchê-la trabalhosamente com queries relacionais entre muitas tabelas diferentes de um banco de dados; Tenho exatamente a mesma representação de objeto no código e no banco de dados.
Da mesma forma, inserir um novo item é simples porque posso criar um objeto JSON a partir de campos em um formulário da web:
1workingJSON[e.name] = e.value;
E então posso escrever isso diretamente no banco de dados:
1submitJSON.createdDate = today;
2if ( submitJSON.section == null ) { submitJSON.section = "news"; }
3submitJSON.submitter = userEmail;
4db.collection('atf').insertOne(submitJSON)
5 .then(returnResponse => {
6 console.log("Return Response: ", returnResponse);
7 window.alert("Submission recorded, thank you!");
8 })
9.catch(errorFromInsert => {
10 console.log("Error from insert: ", errorFromInsert);
11 window.alert("Submission failed, sorry!");
12});
Há um pouco mais de feedback detalhado e tratamento de erros nesta parte do código do que em algumas outras partes do código, já que outras pessoas além de mim usam essa parte do aplicativo!

Agregando um problema

Tanto faz inserir notícias no banco de dados. E quando alguém quer, você sabe, ler uma edição do boletim informativo? A primeira coisa que preciso fazer é falar com o banco de dados do MongoDB Atlas e descobrir qual é o problema mais recente, onde um problema é definido como o conjunto de todas as notícias com a mesma data de publicação. O MongoDB tem um recurso chamado aggregation pipeline, que funciona um pouco como canalizar dados de um comando para outro em uma shell UNIX. Um pipeline de agregação tem vários estágios, cada um dos quais faz uma transformação nos dados de entrada e os passa para o próximo estágio. É uma ótima maneira de realizar queries mais complexas, como agrupar documentos, manipular arrays, remodelar documentos em diferentes modelos e assim por diante, mantendo cada etapa individual fácil de raciocinar e depurar.
No meu caso, usei um pipeline de agregação muito simples para recuperar as datas de publicação mais recentes no banco de dados, com três etapas. No primeiro estágio, usando $group, obtenho todas as datas de publicação. No segundo estágio, uso $match para remover quaisquer datas nulas, que correspondem a itens sem data de publicação, ou seja, itens não publicados. Finalmente, ordeno as datas, usando — você adivinhou — $sort para obter as datas mais recentes.
1let latestIssueDate = db.collection('atf').aggregate( [
2 { $match : { _id: {$ne: null }}},
3 { $group : { _id : "$publishedDate" } },
4 { $sort: { _id: -1 }}
5]).asArray().then(latestIssueDate => {
6 thisIssueDate = latestIssueDate[0]._id;
7 prevIssueDate = latestIssueDate[1]._id;
8 ATFmakeIssueNav(thisIssueDate, prevIssueDate);
9theIssue = { published: "true", publishedDate: thisIssueDate };
10db.collection('atf').find(theIssue).asArray().then(dbItems => {
11 orderSections(dbItems); })
12 .catch(err => { console.error(err) });
13}).catch(err => { console.error(err) });
Desde que eu tenha uma lista de todas as datas de publicação, posso usar a próxima data mais recente para os controles de navegação que permitem que os leitores consultem as edições anteriores do boletim informativo. O uso mais importante, no entanto, é recuperar a questão atual, ou seja, a lista de todos os itens com a data de publicação mais recente. É o que o comandofind() faz e usa como argumento um documento simples:
1{ published: "true", publishedDate: thisIssueDate }
Em outras palavras, gostaria de todos os documentos publicados (não os rascunhos que estão na fila esperando para serem publicados) e em que a data de publicação seja a data mais recente que encontrou com o aggregation pipeline acima.
Essa referência a orderSections é uma função utilitária que garante que as seções do boletim informativo saiam na ordem correta. Também posso detectar quaisquer erros que ocorram, seja no pipeline de agregação ou na própria operação de localização.

Juntando tudo

Neste ponto, publicar um boletim informativo é uma questão de selecionar quais itens serão incluídos na edição e atualizar a data de publicação de todos esses itens:
1const toPublish = { _id: { '$in': itemsToPublish } };
2let today = new Date();
3const update = { '$set': { publishedDate: today, published: "true" } };
4const options = {};
5db.collection('atf').updateMany(toPublish, update, options)
6 .then(returnResponse => {console.log("Return Response: ", returnResponse);})
7 .catch(errorFromUpdate => {console.log("Error from update: ", errorFromUpdate);});
O comando updateMany() tem três documentos como argumentos.
  • O primeiro, o filtro, especifica quais documentos atualizar, o que aqui significa todos os com um ID na arrayitemsToPublish .
  • A segunda é a atualização real que vamos fazer, que é definir o publishedDate para a data de hoje e marcá-lo como publicado.
  • O terceiro argumento, opcional, está vazio no meu caso porque não preciso especificar nenhuma opção.

Movendo correspondência

Agora eu mesmo poderia enviar e-mails do Stitch, mas já usamos um serviço especializado externo que tem uma boa REST API. Usei uma função de ponto para montar as chamadas HTTP e me comunicar com esse serviço externo. As funções do Stitch são uma maneira superfácil de executar funções JavaScript simples na plataforma sem servidor do Stitch, facilitando a implementação da lógica de aplicativos, a integração segura com serviços e microsserviços na nuvem e a criação de APIs - exatamente o meu caso de uso!
Configurei um HTTP Service simples, que posso acessar facilmente assim:
1const http = context.services.get("mcPublish");
Como é comum, a REST API que deseja usar requer uma chave de API. Eu gerei a chave no site deles, mas não quero deixá-la por aí. Felizmente, o Stitch também me permite definir um segredo, então não preciso dessa chave API em texto simples:
1let mcAPIkey = context.values.get("MCsecret");
E isso (além de 1200 mais linhas de casos especiais, funções administrativas, soluções alternativas e miscelânea) é isso. Mas eu queria um pouco mais de visibilidade sobre quais tópicos eram populares, quem estava usando o serviço e assim por diante. Como fazer isso?

Gráficos super fáceis

Felizmente, há uma resposta lógica às minhas preces na forma de MongoDB Atlas Charts, outra parte da plataforma MongoDB cloud, que me permite criar rapidamente uma visualização da atividade no back-end.
MongoDB Charts
Veja como isso é simples: Tenho meu banco de dados, imaginativamente denominado "newsletter", e a collection, denominada "atf" para Above the Fold, o nome do boletim informativo que herdei. Posso ver todos os campos do meu documento, de modo que posso usar o campo _idpara o eixo X e, em seguida, ocreatedDate para o eixo Y, classificando por mês, para criar um gráfico em tempo real do número de notícias enviadas a cada mês.
Configurações para MongoDB Charts
É realmente muito fácil criar visualizações no Atlas Charts, incluindo as muito mais complicadas do que essa, usando todos os tipos de dados avançados do MongoDB. Dê uma olhada em algumas das opções mais avançadas e experimente com seus próprios dados ou com os dados de amostra em uma MongoDB Atlas gratuito.
Foi uma grande experiência de aprendizado construir essa coisa, e todo o exercício me renovou a visão do poder do MongoDB, do document model e da plataforma estendida do MongoDB Cloud - tanto o MongoDB Atlas quanto os serviços correlacionados, como Stitch e Atlas Charts. Também há espaço para expansão; uma das próximas funcionalidades que preciso construir é a de procurar, usando a funcionalidadede pesquisa de texto do MongoDB Atlas.

Para você

Como mencionei no início, uma das coisas boas desse projeto é que ele se encaixa na camada grátis do MongoDB Atlas, Stitch e Charts. Você pode se inscrever em sua própria instância gratuita para sempre e começar a criar hoje, nenhum cartão de crédito necessário e nenhuma data de expiração. Há um assistente de integração útil que orientará você no carregamento de alguns dados de exemplo e na execução de algumas tarefas básicas e, quando você estiver pronto para Go, os Docs serão de primeira, com muitos exemplos executados. Quando você entrar nele e quiser aprender mais, o melhor lugar para procurar é na MongoDB University, que lhe dá a oportunidade de aprender MongoDB no seu próprio passo. Você também pode obter a certificação no MongoDB, o que o incluirá em nossa lista pública de profissionais certificados no MongoDB.

Ícone do FacebookÍcone do Twitterícone do linkedin
Avalie esse Artigo
star-empty
star-empty
star-empty
star-empty
star-empty
Relacionado
Tutorial

Adicionando preenchimento automático aos seus aplicativos Laravel com Atlas Search


Dec 03, 2024 | 9 min read
Artigo

Mapa do Coronavírus e rastreador de dados ao vivo com o MongoDB Charts


Nov 15, 2023 | 3 min read
Tutorial

Criação de um agente de AI aprimorado para memória com o laudo do Aconnection no Amazon Cama do MongoDB Atlas


Oct 29, 2024 | 8 min read
Tutorial

Como implementar fluxos de trabalho do Databricks e o Atlas Vector Search para melhorar a precisão da pesquisa de comércio eletrônico


Sep 18, 2024 | 6 min read
Sumário