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

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

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.


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

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.


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!


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


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


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

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

0

puedes usar este comando para lograrlo:

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

Al usar nuestro sitio, usted reconoce que ha leído y comprende nuestra Política de Cookies y Política de Privacidad.
Licensed under cc by-sa 3.0 with attribution required.