DEV Community

Poveda
Poveda

Posted on

4

Exportando dados filtrados em mais de uma collection

Imagine a seguinte situação:

A equipe estratégica da montadora deseja criar um relatório contendo todas as vendas feitas no mês de agosto de 2020 tanto pela concessionária quanto direto pela fábrica.
O sistema da montadora divide essas vendas em duas collections do mongo.
O relatório é gerado por uma ferramenta consolidada de mercado que aceita a importação dos dados por arquivos .csv ou .json

A primeira solução que vem à cabeça é utilizar o mongoexport com o parâmetro --query para gerar os dados solicitados. No entanto, o mongoexport possui a limitação de só exportar dados de uma única collection por vez.
Fazendo um teste simples de exportar todos os dados de um database sem definir uma collection com o mongoexport obtemos o seguinte resultado:

#$> mongoexport mongodb://localhost:27017 --db examples #comando executado
2021-08-26T08:39:03.607-0300    must specify a collection
2021-08-26T08:39:03.615-0300    try 'mongoexport --help' for more information
Enter fullscreen mode Exit fullscreen mode

Usando o mongosh

O mongosh é a ferramenta básica para interagir com qualquer mongodb. Utilizando ele é possível criar consultas, procedures, indexes e gerenciar o database de maneira geral. Outro ponto interessante é que possível importar scripts .js e executá-los dentro do mongosh. É possível importar o arquivo de duas formas:

  1. Importar diretamente dentro do mongosh
mongosh mongodb://localhost:27017
> load('export_data_multiple_databases/obter_vendas.js')
Enter fullscreen mode Exit fullscreen mode
  1. Importar no momento da execução do mongosh
mongosh mongodb://localhost:27017/examples ~/export_data_multiple_databases/obter_vendas.js 
Enter fullscreen mode Exit fullscreen mode

No primeiro caso os resultados gerados são mostrados diretamente no console do mongosh (contexto do mongosh), tornando a tarefa exportar os dados complexa para o cenário apresentado.

Exemplo de execução

Current Mongosh Log ID: 612918a2e3f888785924e0e9
Connecting to:          mongodb://localhost:27017/examples?directConnection=true&serverSelectionTimeoutMS=2000
Using MongoDB:          5.0.0
Using Mongosh Beta:     0.14.0

For mongosh info see: https://docs.mongodb.com/mongodb-shell/

------
   The server generated these startup warnings when booting:
   2021-08-27T10:16:56.220+00:00: Using the XFS filesystem is strongly recommended with the WiredTiger storage engine. See http://dochub.mongodb.org/core/prodnotes-filesystem
   2021-08-27T10:16:56.525+00:00: Access control is not enabled for the database. Read and write access to data and configuration is unrestricted
   2021-08-27T10:16:56.526+00:00: /sys/kernel/mm/transparent_hugepage/enabled is 'always'. We suggest setting it to 'never'
------
> load('~/export_data_multiple_databases/obter_vendas.js')
[{
  fabricante: 'Lexus',
  modelo: 'LS',
  ano: 2004,
  datavenda: ISODate("2021-08-03T00:00:00.000Z"),
  preco: '$106375.36',
  collectionName: 'vendas_concessionaria'
},
{
  fabricante: 'GMC',
...
Enter fullscreen mode Exit fullscreen mode

Já no segundo caso é possível exportar diretamente para um arquivo externo, pois o comando devolve o resultado no contexto do console e não no contexto do mongosh.

Importante ressaltar que o script importado fica disponível somente naquela sessão.

Exportando para um arquivo

A forma mais simples de exportar para um arquivo é justamente usando o segundo comando de importação de scripts.

mongosh mongodb://localhost:27017/examples ~/export_data_multiple_databases/obter_vendas.js > arquivo_resultado.json
Enter fullscreen mode Exit fullscreen mode

Mongosh --eval

O parâmetro --eval executa um script js inline usando o contexto do mongosh, porém sem carregar o ambiente do mongosh no console. O resultado é da execução é enviado para o console conforme exemplo abaixo:

mongosh mongodb://localhost:27017/examples --eval="load('export_data_multiple_databases/obter_massa_dados.js');"
Enter fullscreen mode Exit fullscreen mode

Como resultado é enviado diretamente para o console (fora do contexto do mongosh), exportar os dados para um arquivo .json é simples

mongosh mongodb://localhost:27017/examples --eval="load('export_data_multiple_databases/obter_massa_dados.js');" > arquivo_resultado.json
Enter fullscreen mode Exit fullscreen mode

A vantagem em relação à exportação padrão é que com o --eval é possível adicionar outras instruções além do que está no script.

Eliminando o cabeçalho com o parâmetro --quiet

Examinando o arquivo exportado, nota-se que os cabeçalhos de inicialização do mongosh também foram exportados.

Current Mongosh Log ID: 6129153e30afffaa9fb76fe4
Connecting to:      mongodb://localhost:27017/examples?directConnection=true&serverSelectionTimeoutMS=2000
Using MongoDB:      5.0.0
Using Mongosh Beta: 0.14.0

For mongosh info see: [1mhttps://docs.mongodb.com/mongodb-shell/]

------
   The server generated these startup warnings when booting:
   2021-08-27T10:16:56.220+00:00: Using the XFS filesystem is strongly recommended with the WiredTiger storage engine. See http://dochub.mongodb.org/core/prodnotes-filesystem
   2021-08-27T10:16:56.525+00:00: Access control is not enabled for the database. Read and write access to data and configuration is unrestricted
   2021-08-27T10:16:56.526+00:00: /sys/kernel/mm/transparent_hugepage/enabled is 'always'. We suggest setting it to 'never'
------

Loading file: ~\export_data_multiple_databases\obter_vendas.js
[{
  fabricante: 'Hyundai',
  modelo: 'Genesis',
  ano: 2009,
...
Enter fullscreen mode Exit fullscreen mode

Para resolver este problema basta adicionar o parâmetro --quiet ao comando de exportação.

Através do método de importação pela linha de comando:

mongosh mongodb://localhost:27017/examples --quiet ~/export_data_multiple_databases/obter_massa_dados.js > arquivo_resultado.json
Enter fullscreen mode Exit fullscreen mode

Usando o --eval:

mongosh mongodb://localhost:27017/examples --quiet --eval="load('export_data_multiple_databases/obter_massa_dados.js');" > arquivo_resultado.json
Enter fullscreen mode Exit fullscreen mode

Ao examinar novamente o arquivo, nota-se que o cabeçalho sumiu e com isso temos um arquivo .json válido e somente com os dados solicitados.

Impressões e Conclusão

A ideia deste post surgiu de uma tarefa que solicitava a exportação de dados oriundos de um schema específico para csv. Tal schema existia em diversas collections com documentos que possuiam campos diferentes entre si. O único ponto em comum dessas collections era justamente um subdocumento com o schema em questão.
Como não sou um profundo conhecedor de mongodb e não encontrei uma forma fácil na documentação e muito menos no stackoverflow e afins, resolvi ser criativo. Me vali da capacidade do mongodb de executar scripts .js e de conhecimentos básicos de shell.

A solução é um tanto verbosa, porém resolveu meu problema de forma simples e eficiente. Imagino que os especialistas em mongodb vão me contar nos comentários:
- basta rodar essa linha de comando que você obtém o mesmo resultado
Mas até lá, vou seguir usando a mesma abordagem para obter esses dados sempre que forem solicitados.

No github (pasta export_data_multiple_databases) deixei o passo a passo de como reproduzir esse post.

Quero deixar um agradecimento especial para o Caio Lucena pelas revisões dos posts publicados até agora.

Referências

https://docs.mongodb.com/mongodb-shell/
Solução do Erro: Como importar data em formato string como tipo date

Image of Datadog

How to Diagram Your Cloud Architecture

Cloud architecture diagrams provide critical visibility into the resources in your environment and how they’re connected. In our latest eBook, AWS Solution Architects Jason Mimick and James Wenzel walk through best practices on how to build effective and professional diagrams.

Download the Free eBook

Top comments (0)

Billboard image

The Next Generation Developer Platform

Coherence is the first Platform-as-a-Service you can control. Unlike "black-box" platforms that are opinionated about the infra you can deploy, Coherence is powered by CNC, the open-source IaC framework, which offers limitless customization.

Learn more