Existe uma maneira de 'bem' imprimir a saída do shell do MongoDB em um arquivo?


101

Especificamente, desejo imprimir os resultados de um mongodb find()em um arquivo. O objeto JSON é muito grande, então não consigo visualizar o objeto inteiro com o tamanho da janela do shell.

Respostas:


216

O shell oferece alguns recursos interessantes, mas ocultos, porque é um ambiente interativo.

Quando você executa comandos de um arquivo javascript por meio do mongo commands.js, você não obterá um comportamento totalmente idêntico.

Existem duas maneiras de contornar isso.

(1) falsificar o shell e fazê-lo pensar que você está no modo interativo

$ mongo dbname << EOF > output.json
db.collection.find().pretty()
EOF

ou
(2) usar Javascript para traduzir o resultado de um find()em um JSON imprimível

mongo dbname command.js > output.json

onde command.js contém isto (ou seu equivalente):

printjson( db.collection.find().toArray() )

Isso imprimirá bastante o array de resultados, incluindo [ ]- se você não quiser, pode iterar sobre o array e printjson()cada elemento.

A propósito, se você estiver executando apenas uma única instrução Javascript, não precisa colocá-la em um arquivo e, em vez disso, pode usar:

$ mongo --quiet dbname --eval 'printjson(db.collection.find().toArray())' > output.json

command.js deve ser um arquivo legível que exista em seu diretório atual e que tenha o javascript que você deseja executar.
Asya Kamsky

Como faço para um db mongo remoto? Eu tentei, mongo blah.mongolab.com:33478/blah -u user -p pass --eval "my query" >> dump.txtmas me deu JavaScript execution failed: SyntaxError: Unexpected token ILLEGAL.
Sheharyar

esse erro significa que o que está dentro de suas aspas após --eval não é uma sintaxe legal. Eu recomendo usar aspas simples fora de expressões inteiras e se você precisar de aspas dentro delas, use aspas duplas para isso.
Asya Kamsky

2
A opção 2 é realmente a única opção se você tiver mais do que um punhado de resultados, já que na opção 1 ela apenas parará em 'Digite "isso" para mais'.
Tomty

2
não exatamente @Tomty - o tamanho do lote do shell é controlável com uma variável dentro do shell. você pode colocar DBQuery.shellBatchSize = 10000 em seu arquivo .mongodbrc.js e ele irá "parar" após 10000 resultados em vez de 20.
Asya Kamsky

29

Como você está fazendo isso em um terminal e deseja apenas inspecionar um registro de maneira sã, você pode usar um truque como este:

mongo | tee somefile

Use a sessão normalmente - db.collection.find().pretty()ou o que quer que você precise fazer, ignore a saída longa e saia. Uma transcrição de sua sessão estará no arquivo em que você teeescreveu.

Esteja ciente de que a saída pode conter sequências de escape e outro lixo devido ao shell do mongo esperar uma sessão interativa. lesslida com isso graciosamente.


12

Basta colocar os comandos que deseja executar em um arquivo, depois passá-los para o shell junto com o nome do banco de dados e redirecionar a saída para um arquivo. Portanto, se o seu comando find estiver find.jse o seu banco de dados estiver foo, terá a seguinte aparência:

./mongo foo find.js >> out.json

Isso não funcionou para mim, apenas imprimi a versão do shell e o nome do banco de dados para out.json. mongo foo < find.js > out.jsonfuncionou.
James Brown

1
esta resposta foi escrita antes de as ferramentas serem reescritas no Go e muitas versões atrás, a menos que você esteja usando algo muito antigo, provavelmente é por isso que não está funcionando para você
Adam Comerford

10

Coloque sua consulta (por exemplo db.someCollection.find().pretty()) em um arquivo javascript, digamos query.js. Em seguida, execute-o no shell do seu sistema operacional usando o comando:

mongo yourDb < query.js > outputFile

O resultado da consulta estará no arquivo denominado 'outputFile'.

Por padrão, o Mongo imprime os primeiros 20 documentos IIRC. Se você quiser mais, pode definir um novo valor para o tamanho do lote no shell do Mongo, por exemplo

DBQuery.shellBatchSize = 100.


Este. Não seja mal direcionado por .jsextensão. Você pode escrever todas aquelas consultas de shell mongo sem alterá-las.
DC,

4

Usando printe JSON.stringifyvocê pode simplesmente produzir um resultado válido JSON .
Use o --quietsinalizador para filtrar o ruído do shell da saída.
Use --norcsinalizador para evitar .mongorc.jsavaliação. (Tive que fazer isso por causa de um formatador bonito que uso, que produz uma saída JSON inválida ) Use a DBQuery.shellBatchSize = ?substituição ?pelo limite do resultado real para evitar paginação.

E, finalmente, use teepara canalizar a saída do terminal para um arquivo:

// Shell:
mongo --quiet --norc ./query.js | tee ~/my_output.json

// query.js:
DBQuery.shellBatchSize = 2000;
function toPrint(data) {
  print(JSON.stringify(data, null, 2));
}

toPrint(
  db.getCollection('myCollection').find().toArray()
);

Espero que isto ajude!


2

Usando esta resposta de Asya Kamsky, escrevi um script de bat de uma linha para Windows. A linha se parece com esta:

mongo --quiet %1 --eval "printjson(db.%2.find().toArray())" > output.json

Então, pode-se executá-lo:

exportToJson.bat DbName CollectionName


2

Consegui salvar o resultado com a função writeFile () .

> writeFile("/home/pahan/output.txt", tojson(db.myCollection.find().toArray()))

A versão do shell do Mongo era 4.0.9


1

Também há mongoexport para isso, mas não tenho certeza de qual versão está disponível.

Exemplo:

mongoexport -d dbname -c collection --jsonArray --pretty --quiet --out output.json

0

Como resposta de Neodan, mongoexport é bastante útil com -qopção de consulta. Ele também converte ObjectIdpara o formato padrão de JSON "$oid". Por exemplo:

mongoexport -d yourdb -c yourcol --jsonArray --pretty -q '{"field": "filter value"}' -o output.json

0

você pode usar este comando para alcançá-lo:

mongo admin -u <userName> -p <password> --quiet --eval "cursor = rs.status(); printjson(cursor)" > output.json

Ao utilizar nosso site, você reconhece que leu e compreendeu nossa Política de Cookies e nossa Política de Privacidade.
Licensed under cc by-sa 3.0 with attribution required.