C'è un modo per stampare in modo "carino" l'output della shell MongoDB su un file?


101

In particolare, voglio stampare i risultati di un mongodb find()su un file. L'oggetto JSON è troppo grande, quindi non riesco a visualizzare l'intero oggetto con le dimensioni della finestra della shell.

Risposte:


216

La shell fornisce alcune caratteristiche carine ma nascoste perché è un ambiente interattivo.

Quando esegui comandi da un file javascript tramite mongo commands.js non otterrai un comportamento del tutto identico.

Ci sono due modi per aggirare questo problema.

(1) simula il guscio e fagli credere di essere in modalità interattiva

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

oppure
(2) utilizzare Javascript per tradurre il risultato di a find()in un JSON stampabile

mongo dbname command.js > output.json

dove command.js contiene questo (o il suo equivalente):

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

Questo stamperà abbastanza l'array di risultati, incluso [ ]- se non vuoi che puoi iterare sull'array e su printjson()ogni elemento.

A proposito, se stai eseguendo solo una singola istruzione Javascript non devi metterla in un file e invece puoi usare:

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

command.js deve essere un file leggibile che esiste nella directory corrente e che ha il javascript che si desidera eseguire.
Asya Kamsky

Come lo faccio per un db mongo remoto? Ho provato mongo blah.mongolab.com:33478/blah -u user -p pass --eval "my query" >> dump.txtma mi ha dato JavaScript execution failed: SyntaxError: Unexpected token ILLEGAL.
Sheharyar

quell'errore significa che cosa c'è dentro le virgolette dopo --eval non è una sintassi legale. Consiglio di utilizzare virgolette singole al di fuori di intere espressioni e se hai bisogno di virgolette al suo interno, usa le virgolette doppie per questo.
Asya Kamsky

2
L'opzione 2 è davvero l'unica opzione se hai più di una manciata di risultati, poiché nell'opzione 1 si fermerà semplicemente su "Digita" it "per altri".
Tomty

2
non proprio @Tomty - la dimensione del batch di shell è controllabile con una variabile all'interno della shell. puoi mettere DBQuery.shellBatchSize = 10000 nel tuo file .mongodbrc.js e "si fermerà" dopo 10000 risultati invece di 20.
Asya Kamsky

29

Dato che lo stai facendo su un terminale e vuoi solo ispezionare un record in modo sano, puoi usare un trucco come questo:

mongo | tee somefile

Usa la sessione come di consueto db.collection.find().pretty()o qualunque cosa tu debba fare, ignora il lungo output ed esci. Una trascrizione della tua sessione sarà nel file teescritto a.

Tieni presente che l'output potrebbe contenere sequenze di escape e altri rifiuti a causa della shell di mongo che si aspetta una sessione interattiva. lessli gestisce con grazia.


12

Basta inserire i comandi che si desidera eseguire in un file, quindi passarlo alla shell insieme al nome del database e reindirizzare l'output a un file. Quindi, se il tuo comando find è in find.jse il tuo database è foo, sarà simile a questo:

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

Questo non ha funzionato per me, ho stampato solo la versione della shell e il nome del db out.json. mongo foo < find.js > out.jsonha funzionato.
James Brown

1
questa risposta è stata scritta prima che gli strumenti venissero riscritti in Go e molte versioni fa, a meno che tu non stia usando qualcosa di molto vecchio, allora probabilmente è per questo che non funziona per te
Adam Comerford

10

Metti la tua query (ad esempio db.someCollection.find().pretty()) in un file javascript, diciamo query.js. Quindi eseguilo nella shell del tuo sistema operativo usando il comando:

mongo yourDb < query.js > outputFile

Il risultato della query sarà nel file denominato "outputFile".

Per impostazione predefinita, Mongo stampa i primi 20 documenti IIRC. Se vuoi di più puoi definire un nuovo valore per la dimensione del batch nella shell Mongo, ad es

DBQuery.shellBatchSize = 100.


Questo. Non essere indirizzato male per .jsestensione. Puoi scrivere tutte quelle belle query di mongo shell senza cambiarle affatto.
d.C.

4

Usando printe JSON.stringifypuoi semplicemente produrre un risultato valido JSON .
Usa --quietflag per filtrare il rumore della shell dall'output.
Usa --norcflag per evitare la .mongorc.jsvalutazione. (Ho dovuto farlo a causa di un bel formattatore che uso, che produce un output JSON non valido ) Usa la DBQuery.shellBatchSize = ?sostituzione ?con il limite del risultato effettivo per evitare il paging.

Infine, usa teeper reindirizzare l'output del terminale a un file:

// 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()
);

Spero che questo ti aiuti!


2

Usando questa risposta di Asya Kamsky, ho scritto uno script bat di una riga per Windows. La linea si presenta così:

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

Quindi si può eseguirlo:

exportToJson.bat DbName CollectionName


2

Sono riuscito a salvare il risultato con la funzione writeFile () .

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

La versione della shell Mongo era 4.0.9


1

C'è anche mongoexport per quello, ma non sono sicuro da quale versione sia disponibile.

Esempio:

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

0

Come risposta di Neodan, mongoexport è abbastanza utile con l' -qopzione per la query. Converte anche ObjectIdnel formato standard di JSON "$oid". Per esempio:

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

0

puoi usare questo comando per ottenerlo:

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

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.