¿Hay alguna manera de imprimir 'bonita' la salida del shell MongoDB en un archivo?

101

Específicamente, quiero imprimir los resultados de un mongodb find()en un archivo. El objeto JSON es demasiado grande, por lo que no puedo ver el objeto completo con el tamaño de la ventana del shell.

víbora
fuente

Respuestas:

216

El shell proporciona algunas características agradables pero ocultas porque es un entorno interactivo.

Cuando ejecuta comandos desde un archivo javascript a través de mongo commands.js, no obtendrá un comportamiento idéntico.

Hay dos formas de evitar esto.

(1) falsifica el caparazón y hazle creer que estás en modo interactivo

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

o
(2) use Javascript para traducir el resultado de a find()en un JSON imprimible

mongo dbname command.js > output.json

donde command.js contiene esto (o su equivalente):

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

Esto imprimirá bastante la matriz de resultados, incluido [ ]: si no lo desea, puede iterar sobre la matriz y printjson()cada elemento.

Por cierto, si está ejecutando una sola declaración de Javascript, no tiene que ponerla en un archivo y en su lugar puede usar:

$ mongo --quiet dbname --eval 'printjson(db.collection.find().toArray())' > output.json
Asya Kamsky
fuente
command.js tiene que ser un archivo legible que exista en su directorio actual y que tenga el javascript que desea ejecutar.
Asya Kamsky
¿Cómo lo hago para un mongo db remoto? Lo intenté mongo blah.mongolab.com:33478/blah -u user -p pass --eval "my query" >> dump.txtpero me dio JavaScript execution failed: SyntaxError: Unexpected token ILLEGAL.
Sheharyar
ese error significa que lo que está dentro de las comillas después de --eval no es una sintaxis legal. Recomiendo usar comillas simples fuera de expresiones completas y si necesita comillas dentro de ellas, use comillas dobles para eso.
Asya Kamsky
2
La opción 2 es realmente la única opción si tiene más de un puñado de resultados, ya que en la opción 1 simplemente se detendrá en 'Escríbalo' para obtener más '.
Tomty
2
no realmente @Tomty: el tamaño del lote de shell se puede controlar con una variable dentro del shell. puede poner DBQuery.shellBatchSize = 10000 en su archivo .mongodbrc.js y se "detendrá" después de 10000 resultados en lugar de 20.
Asya Kamsky
29

Dado que está haciendo esto en una terminal y solo desea inspeccionar un registro de una manera sensata, puede usar un truco como este:

mongo | tee somefile

Use la sesión como de costumbre, db.collection.find().pretty()o lo que sea que necesite hacer, ignore la salida larga y salga. Una transcripción de su sesión estará en el archivo teeescrito.

Tenga en cuenta que la salida puede contener secuencias de escape y otra basura debido a que el shell mongo espera una sesión interactiva. lessmaneja estos con gracia.

Halcón momot
fuente
12

Simplemente coloque los comandos que desea ejecutar en un archivo, luego páselo al shell junto con el nombre de la base de datos y redirija la salida a un archivo. Entonces, si su comando de búsqueda está adentro find.jsy su base de datos lo está foo, se vería así:

./mongo foo find.js >> out.json
Adam Comerford
fuente
Esto no funcionó para mí, solo imprimí la versión de shell y el nombre de la base de datos en out.json. mongo foo < find.js > out.jsonfuncionó.
James Brown
1
esta respuesta se escribió antes de que las herramientas se reescribieran en Go y hace muchas versiones, a menos que esté usando algo muy antiguo, entonces probablemente esa sea la razón por la que no le está funcionando
Adam Comerford
10

Ponga su consulta (por ejemplo db.someCollection.find().pretty()) en un archivo javascript, digamos query.js. Luego ejecútelo en el shell de su sistema operativo usando el comando:

mongo yourDb < query.js > outputFile

El resultado de la consulta estará en el archivo llamado 'outputFile'.

De forma predeterminada, Mongo imprime los primeros 20 documentos IIRC. Si desea más, puede definir un nuevo valor para el tamaño del lote en Mongo shell, por ejemplo

DBQuery.shellBatchSize = 100.

JohnP
fuente
Esta. No se deje engañar por la .jsextensión. Puede escribir todas esas agradables consultas de mongo shell sin cambiarlas en absoluto.
AD
4

Usando printy JSON.stringifypuede simplemente producir un resultado válido JSON .
Utilice la --quietbandera para filtrar el ruido de la carcasa de la salida.
Utilice la --norcbandera para evitar la .mongorc.jsevaluación. (Tuve que hacerlo debido a un bonito formateador que uso, que produce una salida JSON no válida ) Use la DBQuery.shellBatchSize = ?sustitución ?con el límite del resultado real para evitar la paginación.

Y finalmente, use teepara canalizar la salida del terminal a un archivo:

// 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 esto ayude!

Dmitry
fuente
2

Usando esta respuesta de Asya Kamsky, escribí un script bat de una línea para Windows. La línea se ve así:

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

Entonces uno puede ejecutarlo:

exportToJson.bat DbName CollectionName

margaretkru
fuente
2

Logré guardar el resultado con la función writeFile () .

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

La versión de shell de Mongo era 4.0.9

Pavel_H
fuente
1

También hay mongoexport para eso, pero no estoy seguro desde qué versión está disponible.

Ejemplo:

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

Como respuesta de Neodan, mongoexport es bastante útil con la -qopción de consulta. También se convierte ObjectIdal formato estándar de JSON "$oid". P.ej:

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

puedes usar este comando para lograrlo:

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

Parimal Jana
fuente