Existe-t-il un moyen d'imprimer «joli» la sortie du shell MongoDB dans un fichier?

101

Plus précisément, je souhaite imprimer les résultats d'un mongodb find()dans un fichier. L'objet JSON est trop grand, je ne peux donc pas afficher l'objet entier avec la taille de la fenêtre shell.

vipère
la source

Réponses:

216

Le shell fournit des fonctionnalités intéressantes mais cachées car c'est un environnement interactif.

Lorsque vous exécutez des commandes à partir d'un fichier javascript via mongo commands.js, vous n'obtiendrez pas un comportement tout à fait identique.

Il y a deux façons de contourner cela.

(1) simulez le shell et faites-lui croire que vous êtes en mode interactif

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

ou
(2) utiliser Javascript pour traduire le résultat d'un find()en un JSON imprimable

mongo dbname command.js > output.json

où command.js contient ceci (ou son équivalent):

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

Cela affichera assez bien le tableau des résultats, y compris [ ]- si vous ne voulez pas que vous puissiez parcourir le tableau et printjson()chaque élément.

Au fait, si vous exécutez une seule instruction Javascript, vous n'avez pas à la mettre dans un fichier et à la place, vous pouvez utiliser:

$ mongo --quiet dbname --eval 'printjson(db.collection.find().toArray())' > output.json
Asya Kamsky
la source
command.js doit être un fichier lisible qui existe dans votre répertoire actuel et qui contient le javascript que vous souhaitez exécuter.
Asya Kamsky
Comment puis-je le faire pour un mongo db distant? J'ai essayé mongo blah.mongolab.com:33478/blah -u user -p pass --eval "my query" >> dump.txtmais ça m'a donné JavaScript execution failed: SyntaxError: Unexpected token ILLEGAL.
Sheharyar
cette erreur signifie que ce qui se trouve à l'intérieur de vos guillemets après --eval n'est pas une syntaxe légale. Je recommande d'utiliser des guillemets simples en dehors des expressions entières et si vous avez besoin de guillemets à l'intérieur, utilisez des guillemets doubles pour cela.
Asya Kamsky
2
L'option 2 est vraiment la seule option si vous avez plus d'une poignée de résultats, car dans l'option 1, elle s'arrêtera simplement à "Tapez" pour plus ".
Tomty
2
pas vraiment @Tomty - la taille du lot de shell est contrôlable avec une variable à l'intérieur du shell. vous pouvez mettre DBQuery.shellBatchSize = 10000 dans votre fichier .mongodbrc.js et il "s'arrêtera" après 10000 résultats au lieu de 20.
Asya Kamsky
29

Puisque vous faites cela sur un terminal et que vous voulez simplement inspecter un enregistrement d'une manière saine, vous pouvez utiliser une astuce comme celle-ci:

mongo | tee somefile

Utilisez la session comme d'habitude - db.collection.find().pretty()ou quoi que vous ayez à faire, ignorez la sortie longue et quittez. Une transcription de votre session sera dans le fichier teeécrit.

N'oubliez pas que la sortie peut contenir des séquences d'échappement et d'autres déchets en raison du mongo shell attend une session interactive. lessgère ces gracieusement.

Faucon Momot
la source
12

Mettez simplement les commandes que vous souhaitez exécuter dans un fichier, puis transmettez-le au shell avec le nom de la base de données et redirigez la sortie vers un fichier. Donc, si votre commande find est dans find.jset que votre base de données l'est foo, cela ressemblerait à ceci:

./mongo foo find.js >> out.json
Adam Comerford
la source
Cela n'a pas fonctionné pour moi, seulement imprimé la version du shell et le nom de la base de données out.json. mongo foo < find.js > out.jsona fonctionné.
James Brown
1
cette réponse a été écrite avant que les outils ne soient réécrits dans Go et il y a de nombreuses versions, à moins que vous n'utilisiez quelque chose de très ancien, c'est probablement pourquoi cela ne fonctionne pas pour vous
Adam Comerford
10

Mettez votre requête (par exemple db.someCollection.find().pretty()) dans un fichier javascript, disons query.js. Ensuite, exécutez-le dans le shell de votre système d'exploitation en utilisant la commande:

mongo yourDb < query.js > outputFile

Le résultat de la requête sera dans le fichier nommé 'outputFile'.

Par défaut, Mongo imprime les 20 premiers documents IIRC. Si vous en voulez plus, vous pouvez définir une nouvelle valeur pour la taille du lot dans Mongo shell, par exemple

DBQuery.shellBatchSize = 100.

JohnP
la source
Ce. Ne soyez pas mal dirigé par l' .jsextension. Vous pouvez écrire toutes ces belles requêtes shell mongo sans les changer du tout.
AD
4

En utilisant printet, JSON.stringifyvous pouvez simplement produire un résultat valide JSON .
Utilisez un --quietdrapeau pour filtrer le bruit du shell de la sortie.
Utilisez un --norcdrapeau pour éviter l' .mongorc.jsévaluation. (J'ai dû le faire à cause d'un joli formateur que j'utilise, qui produit une sortie JSON invalide ) Utilisez le DBQuery.shellBatchSize = ?remplacement ?par la limite du résultat réel pour éviter la pagination.

Et enfin, utilisez teepour diriger la sortie du terminal vers un fichier:

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

J'espère que cela t'aides!

Dmitry
la source
2

En utilisant cette réponse d'Asya Kamsky, j'ai écrit un script de batte d'une ligne pour Windows. La ligne ressemble à ceci:

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

Ensuite, on peut l'exécuter:

exportToJson.bat DbName CollectionName

margaretkru
la source
2

J'ai réussi à enregistrer le résultat avec la fonction writeFile () .

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

La version du shell Mongo était 4.0.9

Pavel_H
la source
1

Il existe également mongoexport pour cela, mais je ne sais pas depuis quelle version il est disponible.

Exemple:

mongoexport -d dbname -c collection --jsonArray --pretty --quiet --out output.json
Néodan
la source
0

Comme réponse de Neodan, mongoexport est très utile avec une -qoption de requête. Il convertit également ObjectIdau format standard de JSON "$oid". Par exemple:

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

vous pouvez utiliser cette commande pour y parvenir:

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

Parimal Jana
la source