Exportando campos específicos com mongoexport
Tags: mongodb, mongoexport, mongotools
Published: 2021-08-12 10:52:39

No post anterior expliquei como filtrar os dados da base antes de exportá-los. O filtro é muito útil para obtermos somente os dados desejados já no momento da exportação e assim reduzir a carga na rede. No entanto, quando a exportação é realizada, o *document* inteiro é exportado. 

> E se quisermos somente alguns campos daquele *document*?

É para esses casos que o mongoexport possui as opções --fields e --fieldFile.

## O parâmetro [--fields](https://docs.mongodb.com/database-tools/mongoexport/#std-option-mongoexport.--fields)

O parâmetro field recebe os campos desejados separados por vírgula diretamente no comando do mongoexport. Pode ser adicionado qualquer campo do document, incluindo os campos de subdocuments.

```shell
mongoexport.exe mongodb://localhost:27017 --db example -c cars --queryFile="~/filter2.json" --fields="ano,fabricante,motorizacao.litros" --csv
```
Note que além do parâmetro --fields, também utilizei o parâmetro --csv para forçar a exportação em csv, pois no json (formato de exportação padrão) existem algumas peculiaridades.

O resultado obtido rodando o comando na nossa base de testes foi o seguinte

```csv
ano,fabricante,motorizacao.litros
1984,Toyota,1.6
1994,Toyota,2.2
1976,Toyota,1.4
2001,Toyota,1.8
1976,Toyota,1.6
```

### Peculiaridades da exportação em json
Quando a opção de exportação é json (default), o campo _id também é exportado, independentemente de ter sido adicionado a lista ou não.
Outra particularidade é que se um campo do subdocument for adicionado como campo de exportação, todos os campos do subdocument serão exportados.

#### Exportação sem um campo do subdocument
```shell
mongoexport.exe mongodb://localhost:27017 --db example -c cars --queryFile="~/filter2.json" --fields="ano,fabricante"
```
O resultado obtido foi o seguinte
```json
{"_id":{"$oid":"60f6e2eefc13ae490c000bb8"},"ano":1984,"fabricante":"Toyota"}
{"_id":{"$oid":"60f6e2eefc13ae490c000d61"},"ano":1994,"fabricante":"Toyota"}
{"_id":{"$oid":"60f6e2effc13ae490c000d91"},"ano":1976,"fabricante":"Toyota"}
{"_id":{"$oid":"60f6e2effc13ae490c000e76"},"ano":2001,"fabricante":"Toyota"}
{"_id":{"$oid":"60f6e2effc13ae490c000e93"},"ano":1976,"fabricante":"Toyota"}
``` 
Conforme foi descrito anteriormente, o campo _id(pk do registro) foi exportado mesmo que ele não conste nos campos no parâmetro --fields

#### Exportação com um campo do subdocument. 
```shell
mongoexport.exe mongodb://localhost:27017 --db example -c cars --queryFile="~/filter2.json" --fields="ano,fabricante, motorizacao.litros"
```
Como pode ser visto neste exemplo, só foi pedido para retornar o campo litros do subdocument motorização, no entando o resultado listado abaixo, mostra que o campo **hp** foi enviado para o resultado final

```json
{"_id":{"$oid":"60f6e2eefc13ae490c000bb8"},"ano":1984,"fabricante":"Toyota","motorizacao":{"litros":1.6,"hp":190}}
{"_id":{"$oid":"60f6e2eefc13ae490c000d61"},"ano":1994,"fabricante":"Toyota","motorizacao":{"litros":2.2,"hp":221}}
{"_id":{"$oid":"60f6e2effc13ae490c000d91"},"ano":1976,"fabricante":"Toyota","motorizacao":{"litros":1.4,"hp":134}}
{"_id":{"$oid":"60f6e2effc13ae490c000e76"},"ano":2001,"fabricante":"Toyota","motorizacao":{"litros":1.8,"hp":140}}
{"_id":{"$oid":"60f6e2effc13ae490c000e93"},"ano":1976,"fabricante":"Toyota","motorizacao":{"litros":1.6,"hp":134}}
```
## O parâmetro [--fieldFile](https://docs.mongodb.com/database-tools/mongoexport/#std-option-mongoexport.--fieldFile)

Com o parâmetro --fieldFile é possível passar o caminho de um arquivo que contém a lista de campos a serem exportados. Cada linha deve conter somente um campo, caso contrário ocorre erro na exportação. Infelizmente este parâmetro só pode ser utilizado para as exportações do tipo **--csv**, sendo ignorado quando a exportação é para json.

```shell
mongoexport.exe mongodb://localhost:27017 --db example -c cars --queryFile="~/filter2.json" --fieldFile="~/fields_to_export.txt" --csv
```
Resultado da execução
```csv
fabricante,ano,motorizacao.hp
Toyota,1984,190
Toyota,1994,221
Toyota,1976,134
Toyota,2001,140
Toyota,1976,134
```
## Impressões e Conclusão
Vejo que estes parâmetros são muito úteis, principalmente se necessitamos exportar determinados campos do banco para um arquivo csv que poderá ser utilizado em algum teste de cargas ou importação em outros sistemas, pois com a seleção dos campos é possível planificar um documento do mongo.
Já para a exportação em json, vejo este método como uma forma de sanitizar campos do documento principal, deixando somente os campos relevantes para uma nova base de dados ou arquivo de mock.

O que me motivou a escrever esse post foi uma extrapolação do [post anterior](https://dev.to/poveda/exportando-dados-filtrados-com-mongoexport-1k36) quando pensei:
> Consegui filtrar os dados, mas e se eu quiser retornar somente determinados campos como no sql? Será que consigo?

No github (pasta fields_mongoexport) deixei o passo a passo de como reproduzir esse post.
{%github https://github.com/julianopoveda/mongoblogposts no-readme %}

## Referencias
https://docs.mongodb.com/database-tools/mongoexport/