在 Mongo shell 中将 Mongo 查询输出打印到文件中

2天大的 Mongo 和我有一个 SQL 的背景,所以忍受我。与 MySQL 一样,在 MySQL 命令行中将查询结果输出到计算机上的文件非常方便。我试图理解我怎样才能做同样的蒙戈,在贝壳里的时候

我可以通过离开 shell 并执行以下命令轻松获得我想要的查询输出:

mongo localhost:27017/dbname --eval "printjson(db.collectionName.findOne())" > sample.json

以上方法是可以的,但是需要我退出 mongo shell 或者打开一个新的终端选项卡来执行这个命令。如果我可以在 shell 中简单地执行这个操作,那将非常方便。

附注: 这个问题是我在 那么上发布的一个问题的分支

142696 次浏览

AFAIK, there is no a interactive option for output to file, there is a previous SO question related with this: Printing mongodb shell output to File

However, you can log all the shell session if you invoked the shell with tee command:

$ mongo | tee file.txt
MongoDB shell version: 2.4.2
connecting to: test
> printjson({this: 'is a test'})
{ "this" : "is a test" }
> printjson({this: 'is another test'})
{ "this" : "is another test" }
> exit
bye

Then you'll get a file with this content:

MongoDB shell version: 2.4.2
connecting to: test
> printjson({this: 'is a test'})
{ "this" : "is a test" }
> printjson({this: 'is another test'})
{ "this" : "is another test" }
> exit
bye

To remove all the commands and keep only the json output, you can use a command similar to:

tail -n +3 file.txt | egrep -v "^>|^bye" > output.json

Then you'll get:

{ "this" : "is a test" }
{ "this" : "is another test" }

If you invoke the shell with script-file, db address, and --quiet arguments, you can redirect the output (made with print() for example) to a file:

mongo localhost/mydatabase --quiet myScriptFile.js > output

It may be useful to you to simply increase the number of results that get displayed

In the mongo shell > DBQuery.shellBatchSize = 3000

and then you can select all the results out of the terminal in one go and paste into a text file.

It is what I am going to do :)

(from : https://stackoverflow.com/a/3705615/1290746)

Combining several conditions:

  • write mongo query in JS file and send it from terminal
  • switch/define a database programmatically
  • output all found records
  • cut initial output lines
  • save the output into JSON file

myScriptFile.js

// Switch current database to "mydatabase"
db = db.getSiblingDB('mydatabase');


// The mark for cutting initial output off
print("CUT_TO_HERE");


// Main output
// "toArray()" method allows to get all records
printjson( db.getCollection('jobs').find().toArray() );

Sending the query from terminal

-z key of sed allows treat output as a single multi-line string

$> mongo localhost --quiet myScriptFile.js | sed -z 's/^.*CUT_TO_HERE\n//' > output.json

We can do it this way -

mongo db_name --quiet --eval 'DBQuery.shellBatchSize = 2000; db.users.find({}).limit(2000).toArray()' > users.json

The shellBatchSize argument is used to determine how many rows is the mongo client allowed to print. Its default value is 20.

There are ways to do this without having to quit the CLI and pipe mongo output to a non-tty.

To save the output from a query with result x we can do the following to directly store the json output to /tmp/x.json:

> EDITOR="cat > /tmp/x.json"
> x = db.MyCollection.find(...).toArray()
> edit x
>

Note that the output isn't strictly Json but rather the dialect that Mongo uses.

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:

fs.writeFileSync('output.json', JSON.stringify(db.collectionName.findOne()))

This also avoid problems such as the ObjectId(...) being included in the tojson result, which is not valid JSON string.

The above code works according to the docs describes:

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 already marked as Legacy, so use the mongosh if possible.