whereswalden
whereswalden

Reputation: 4959

Force mongodb to output strict JSON

I want to consume the raw output of some MongoDB commands in other programs that speak JSON. When I run commands in the mongo shell, they represent Extended JSON, fields in "shell mode", with special fields like NumberLong , Date, and Timestamp. I see references in the documentation to "strict mode", but I see no way to turn it on for the shell, or a way to run commands like db.serverStatus() in things that do output strict JSON, like mongodump. How can I force Mongo to output standards-compliant JSON?

There are several other questions on this topic, but I don't find any of their answers particularly satisfactory.

Upvotes: 55

Views: 26404

Answers (5)

agelbess
agelbess

Reputation: 4351

In case of findOne

JSON.stringify(db.Bill.findOne({'a': '123'}))

In case of a cursor

db.Bill.find({'a': '123'}).forEach(r=>print(JSON.stringify(r)))

or

print('[') + db.Bill.find().limit(2).forEach(r=>print(JSON.stringify(r) + ',')) + print(']')

will output

[{a:123},{a:234},]

the last one will have a ',' after the last item...remove it

Upvotes: 4

DeBraid
DeBraid

Reputation: 9451

EDIT: This will transform a given document, but will not work on a list of documents. Changed find to findOne.

Adding

.forEach(function(results){results._id=results._id.toString();printjson(results)})`

to a findOne() will output valid JSON.

Example:

db
  .users
  .findOne()
  .forEach(function (results) {
    results._id = results._id.toString();
    printjson(results)
  })

Source: https://www.mydbaworld.com/mongodb-shell-output-valid-json/

Upvotes: -1

Kieveli
Kieveli

Reputation: 11075

To build on the answer from @jbyler, you can strip out the numberLongs using sed after you get your data - that is if you're using linux.

mongoexport --jsonArray -d dbName -c collection -q '{fieldName: {$regex: ".*turkey.*"}}' | sed -r 's/\{ "[$]numberLong" : "([0-9]+)" }/"\1"/g' | json_pp

Upvotes: 1

jbyler
jbyler

Reputation: 7847

I have not found a way to do this in the mongo shell, but as a workaround, mongoexport can run queries and its output uses strict mode and can be piped into other commands that expect JSON input (such as json_pp or jq). For example, suppose you have the following mongo shell command to run a query, and you want to create a pipeline using that data:

db.myItemsCollection.find({creationDate: {$gte: ISODate("2016-09-29")}}).pretty()

Convert that mongo shell command into this shell command, piping for the sake of example to `json_pp:

mongoexport --jsonArray -d myDbName -c myItemsCollection -q '{"creationDate": {"$gte": {"$date": "2016-09-29T00:00Z"}}}' | json_pp

You will need to convert the query into strict mode format, and pass the database name and collection name as arguments, as well as quote properly for your shell, as shown here.

Upvotes: 7

whereswalden
whereswalden

Reputation: 4959

The MongoDB shell speaks Javascript, so the answer is simple: use JSON.stringify(). If your command is db.serverStatus(), then you can simply do this:

JSON.stringify(db.serverStatus())

This won't output the proper "strict mode" representation of each of the fields ({ "floatApprox": <number> } instead of { "$numberLong": "<number>" }), but if what you care about is getting standards-compliant JSON out, this'll do the trick.

Upvotes: 47

Related Questions