Estou usando o MongoDB 2.2.2 para máquina Windows7 de 32 bits. Eu tenho uma consulta de agregação complexa em um arquivo .js. Preciso executar este arquivo no shell e direcionar a saída para um arquivo CSV. Asseguro-me de que a consulta retorne um json "simples" (sem chaves aninhadas), portanto, é inerentemente conversível em um csv puro.
Eu sei sobre load()
e eval()
. eval()
requer que eu cole toda a consulta no shell e permite apenas printjson()
dentro do script, enquanto eu preciso do csv. E, a segunda forma: load()
..Imprime a saída na tela, e novamente no formato json.
Existe uma maneira de o Mongo fazer essa conversão de json para csv? (Eu preciso do arquivo csv para preparar gráficos sobre os dados). Estou pensando:
1. Ou o mongo tem um comando integrado para isso que não consigo encontrar no momento.
2. Mongo não pode fazer isso por mim; Posso no máximo enviar a saída json para um arquivo que eu mesmo preciso converter para csv.
3. O Mongo pode enviar a saída json para uma coleção temporária, cujo conteúdo pode ser facilmente mongoexported
para o formato csv. Mas acho que apenas as consultas de redução de mapa suportam coleções de saída. Isso está certo? Eu preciso disso para uma consulta de agregação.
Obrigado por qualquer ajuda :)
fonte
Respostas:
Sei que esta pergunta é antiga, mas passei uma hora tentando exportar uma consulta complexa para csv e queria compartilhar minhas ideias. Primeiro, não consegui fazer nenhum dos conversores json para csv funcionarem (embora este parecesse promissor). O que acabei fazendo foi escrever manualmente o arquivo csv no meu script mongo.
Esta é uma versão simples, mas essencialmente o que eu fiz:
print("name,id,email"); db.User.find().forEach(function(user){ print(user.name+","+user._id.valueOf()+","+user.email); });
Acabei de canalizar a consulta para stdout
mongo test export.js > out.csv
onde
test
está o nome do banco de dados que uso.fonte
use <database>
ao início do scripttest
no último comando é o nome do banco de dados, apenas substitua pelo nome do seu banco de dados.A exportação embutida do Mongo está funcionando bem, a menos que você queira qualquer manipulação de dados, como formato de data, tipos de dados ocultos, etc.
Seguir o comando funciona como um encanto.
mongoexport -h localhost -d databse -c collection --type=csv --fields erpNum,orderId,time,status -q '{"time":{"$gt":1438275600000}, "status":{"$ne" :"Cancelled"}}' --out report.csv
fonte
--type=csv
vez de--csv
.Estendendo outras respostas:
Achei a resposta de @ GEverding mais flexível. Também funciona com agregação:
test_db.js
print("name,email"); db.users.aggregate([ { $match: {} } ]).forEach(function(user) { print(user.name+","+user.email); } });
Execute o seguinte comando para exportar os resultados:
Infelizmente, ele adiciona texto adicional ao arquivo CSV, o que requer o processamento do arquivo antes de podermos usá-lo:
MongoDB shell version: 3.2.10 connecting to: test_db
Mas podemos fazer o shell mongo parar de cuspir esses comentários e apenas imprimir o que pedimos passando a
--quiet
bandeirafonte
Aqui está o que você pode tentar:
print("id,name,startDate") cursor = db.<collection_name>.find(); while (cursor.hasNext()) { jsonObject = cursor.next(); print(jsonObject._id.valueOf() + "," + jsonObject.name + ",\"" + jsonObject.stateDate.toUTCString() +"\"") }
Salve em um arquivo, diga "export.js". Execute o seguinte comando:
mongo <host>/<dbname> -u <username> -p <password> export.js > out.csv
fonte
Dê uma olhada nisso
para a saída do shell mongo para o arquivo. Não há suporte para a saída de csv do shell mongos. Você teria que escrever o javascript sozinho ou usar um dos muitos conversores disponíveis. Google "converter json para csv", por exemplo.
fonte
Só estou pensando aqui com uma boa solução que tenho usado. Isso é semelhante à solução de Lucky Soni acima, pois oferece suporte à agregação, mas não requer codificação permanente dos nomes dos campos.
cursor = db.<collection_name>.<my_query_with_aggregation>; headerPrinted = false; while (cursor.hasNext()) { item = cursor.next(); if (!headerPrinted) { print(Object.keys(item).join(',')); headerPrinted = true; } line = Object .keys(item) .map(function(prop) { return '"' + item[prop] + '"'; }) .join(','); print(line); }
Salve isso como um
.js
arquivo, neste caso, vamos chamá-loexample.js
e executá-lo com a linha de comando mongo assim:fonte
Eu uso a seguinte técnica. Isso torna mais fácil manter os nomes das colunas sincronizados com o conteúdo:
var cursor = db.getCollection('Employees.Details').find({}) var header = [] var rows = [] var firstRow = true cursor.forEach((doc) => { var cells = [] if (firstRow) header.push("employee_number") cells.push(doc.EmpNum.valueOf()) if (firstRow) header.push("name") cells.push(doc.FullName.valueOf()) if (firstRow) header.push("dob") cells.push(doc.DateOfBirth.valueOf()) row = cells.join(',') rows.push(row) firstRow = false }) print(header.join(',')) print(rows.join('\n'))
fonte
Ao executar um script em um servidor remoto. O Mongo adicionará sua própria saída de registro, que podemos querer omitir de nosso arquivo.
--quiet
opção irá apenas desativar os logs relacionados à conexão. Nem todos os logs do mongo. Nesse caso, talvez seja necessário filtrar as linhas desnecessárias manualmente. Um exemplo baseado em Windows:mongo dbname --username userName --password password --host replicaset/ip:port --quiet printDataToCsv.js | findstr /v "NETWORK" > data.csv
Isso canalizará a saída do script e usará
findstr
para filtrar quaisquer linhas que contenham a string NETWORK. Mais informações sobre findstr: https://docs.microsoft.com/en-us/windows-server/administration/windows-commands/findstrUma versão Linux disso usaria
grep
.fonte