有没有一种“漂亮”地将 MongoDB shell 输出打印到文件中的方法?

具体来说,我想将 mongodb find()的结果打印到一个文件中。JSON 对象太大了,所以我无法查看 shell 窗口大小的整个对象。

127442 次浏览

Just put the commands you want to run into a file, then pass it to the shell along with the database name and redirect the output to a file. So, if your find command is in find.js and your database is foo, it would look like this:

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

The shell provides some nice but hidden features because it's an interactive environment.

When you run commands from a javascript file via mongo commands.js you won't get quite identical behavior.

There are two ways around this.

(1) fake out the shell and make it think you are in interactive mode

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

or
(2) use Javascript to translate the result of a find() into a printable JSON

mongo dbname command.js > output.json

where command.js contains this (or its equivalent):

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

This will pretty print the array of results, including [ ] - if you don't want that you can iterate over the array and printjson() each element.

By the way if you are running just a single Javascript statement you don't have to put it in a file and instead you can use:

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

Since you are doing this on a terminal and just want to inspect a record in a sane way, you can use a trick like this:

mongo | tee somefile

Use the session as normal - db.collection.find().pretty() or whatever you need to do, ignore the long output, and exit. A transcript of your session will be in the file tee wrote to.

Be mindful that the output might contain escape sequences and other garbage due to the mongo shell expecting an interactive session. less handles these gracefully.

Put your query (e.g. db.someCollection.find().pretty()) to a javascript file, let's say query.js. Then run it in your operating system's shell using command:

mongo yourDb < query.js > outputFile

Query result will be in the file named 'outputFile'.

By default Mongo prints out first 20 documents IIRC. If you want more you can define new value to batch size in Mongo shell, e.g.

DBQuery.shellBatchSize = 100.

Using this answer from Asya Kamsky, I wrote a one-line bat script for Windows. The line looks like this:

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

Then one can run it:

exportToJson.bat DbName CollectionName

Using print and JSON.stringify you can simply produce a valid JSON result.
Use --quiet flag to filter shell noise from the output.
Use --norc flag to avoid .mongorc.js evaluation. (I had to do it because of a pretty-formatter that I use, which produces invalid JSON output) Use DBQuery.shellBatchSize = ? replacing ? with the limit of the actual result to avoid paging.

And finally, use tee to pipe the terminal output to a 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()
);

Hope this helps!

Also there is mongoexport for that, but I'm not sure since which version it is available.

Example:

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

As answer by Neodan mongoexport is quite useful with -q option for query. It also convert ObjectId to standard format of JSON "$oid". E.g:

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

I managed to save result with writeFile() function.

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

Mongo shell version was 4.0.9

you can use this command to acheive it:

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

In the new mongodb shell 5.0+ mongosh, it integrate the Node.js fs module, so you can simply do below in the new mongosh shell for pretty print the output:

fs.writeFileSync('output.json', JSON.stringify(db.test.find().toArray(), null, 2))

Without any problems such as the ObjectId has been stripped, etc., which is better than the printjson or .pretty().

The above code can work as the description denotes:

The MongoDB Shell, mongosh, is a fully functional JavaScript and Node.js 14.x REPL environment for interacting with MongoDB deployments. You can use the MongoDB Shell to test queries and operations directly with your database.

The old mongo shell also marked as Legacy, so you should move to this new way.