« Back to Blog
BLOG POST

Get the names of all keys in a MongoDB collection

MongoDB Support

By MongoDB Support

Posted on: January 18, 2019

In order to validate your schema, debug for typos in fields, or find fields that aren’t supposed to be set, you’ll need to get an understanding of all the keys in your MongoDB collection.

Many MongoDB-as-a-service companies offer an easy way to do this right in the UI, including ObjectRocket. Seasoned MongoDB users typically start with an object-document mapper (ODM), such as Mongoose for JS or Mongoengine for Python, so they can build a consistent schema for their application and reduce typos. (ODMs also do type validation, so you aren’t accidentally putting a string in a field that has integers and has math applied to it.)

If you don’t have a service or ODM, there are several other methods you can use to access the keys. Here are the best ways we’ve found to get all the keys in a MongoDB collection for different circumstances.

An example

db.activities.insert( { type : [‘indoor’, 'outdoor' , ‘mixed’] } );
db.activities.insert( { activity : 'cycling' } );
db.activities.insert( { activity : ‘skiing’, location: ‘Alpes’, } );
db.activities.insert( { equipment : [‘paddles’,‘sunglasses’] } );

You’d like to get the unique keys:
type, activity, equipment, location

MapReduce

You can do this with MapReduce:

mr = db.runCommand({ "mapreduce" : "activities", "map" : function() { for (var key in this) { emit(key, null); } }, "reduce" : function(key, stuff) { return null; }, "out": "activities" + "_keys" })

Once that’s complete, run the distinct command on the resulting collection to find all keys:

db.activities_keys.distinct("_id")

If you want to get a list of all the unique keys in a subdocument, just modify this line:

for (var key in this.first_level.second_level.nth_level) { emit(key, null); }

Aggregation

You can also use aggregation. This method works with all drivers that support the aggregate framework. With your aggregations, $sample or $limit can be used to reduce overhead.

Note: Running with primary read preference may impact performance. Consider running with secondary read preference.

Use aggregation with $objectToArrray (available in version 3.4.4 and up) to convert all top key and value pairs into document arrays followed by $unwind and $group with $addToSet to get distinct keys across entire collection.

$$ROOT for referencing the top level document.

db.activities.aggregate([ {"$project":{"arrayofkeyvalue":{"$objectToArray":"$$ROOT"}}}, {"$unwind":"$arrayofkeyvalue"}, {"$group":{"_id":null,"allkeys":{"$addToSet":"$arrayofkeyvalue.k"}}} ])

Get keys in a single document

You can also use aggregation to get keys in a single document:

db.activities.aggregate([ {"$project":{"arrayofkeyvalue":{"$objectToArray":"$$ROOT"}}}, {"$project":{"keys":"$arrayofkeyvalue.k"}} ])

Mongo shell

You can also try this under mongo shell client:

var allKeys = {}; db.YOURCOLLECTION.find().forEach(function(doc){Object.keys(doc).forEach(function(key){allKeys[key]=1})}); allKeys;

Output fields for a single document

If you need the output of fields for a single document in a collection (since the others may all have completely different keys) use the following:

doc=db.thinks.findOne(); for (key in doc) print(key);

Python

Or, you can use Python. This returns the set of all top-level keys in the collection:

#Using pymongo and connection named 'db' reduce( lambda all_keys, rec_keys: all_keys | set(rec_keys), map(lambda d: d.keys(), db.things.find()), set() )

JavaScript

Or, you can use JavaScript:

db.collection('collectionName').mapReduce( function() { for (var key in this) { emit(key, null); } }, function(key, stuff) { return null; }, { "out": "allFieldNames" }, function(err, results) { var fields = db.collection('allFieldNames').distinct('_id'); fields .then(function(data) { var finalData = { "status": "success", "fields": data }; res.send(finalData); delteCollection(db, 'allFieldNames'); }) .catch(function(err) { res.send(err); delteCollection(db, 'allFieldNames'); }); });

After reading the newly created collection “allFieldNames”, delete it.

db.collection("allFieldNames").remove({}, function (err,result) { db.close(); return; });

So many options…

You’ve got a lot of options to get these Mongo keys! If you’re overwhelmed by MongoDB management and want to focus on your code instead of database management, we’re here for you. Give our database platform and our white glove support a try for free.

eBook: Everything you need to know about DBaaS

Learn why DBaaS is booming and get a checklist of questions to ask vendors to find the right fit for your business.

Learn More →

DBaaS for Elasticsearch Jetpack

eBook: DBaaS for Elasticsearch Jetpack

Everything you need to know about Elasticsearch with Kibana. Plus, learn how DBaaS can save you time and money.

Learn More →

Keep in the know!

Subscribe to our emails and we’ll let you know what’s going on at ObjectRocket. We hate spam and make it easy to unsubscribe.