Exportando campos específicos com mongoexport

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

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.

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

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

mongoexport.exe mongodb://localhost:27017 --db example -c cars --queryFile="~/filter2.json" --fields="ano,fabricante"

O resultado obtido foi o seguinte

{"_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.

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

{"_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

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.

mongoexport.exe mongodb://localhost:27017 --db example -c cars --queryFile="~/filter2.json" --fieldFile="~/fields_to_export.txt" --csv

Resultado da execução

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 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.

Referencias

10