MongoDB: how to count number of keys in a document?
In Mongo (as in most NoSQL solutions) it's usually a good idea to pre-calculate such values if you want to do queries on them later (e.g. "where the number of different keys > 12") so maybe you should consider adding a new field "keyCount" which you increment every time a new key is added.
There's no built-in command for that. Fetch this document and count the keys yourself.
Quite possible if using MongoDB 3.6 and newer though the aggregation framework.
Use the $objectToArray
operator within an aggregation pipeline to convert the document to an array. The return array contains an element for each field/value pair in the original document. Each element in the return array is a document that contains two fields k
and v
.
The reference to root the document is made possible through the $$ROOT
system variable which references the top-level document currently being processed in the aggregation pipeline stage.
On getting the array, you can then leverage the use of $addFields
pipeline step to create a field that holds the counts and the actual count is derived with the use of the $size
operator.
All this can be done in a single pipeline by nesting the expressions as follows:
db.collection.aggregate([
{ "$addFields": {
"count": {
"$size": {
"$objectToArray": "$$ROOT"
}
}
} }
])
Example Output
{
"_id" : ObjectId("5a7cd94520a31e44e0e7e282"),
"a" : 1.0,
"b" : 1.0,
"c" : 2.0,
"z" : 2.0,
"count" : 5
}
To exclude the _id
field, you can use the $filter
operator as:
db.collection.aggregate([
{
"$addFields": {
"count": {
"$size": {
"$filter": {
"input": { "$objectToArray": "$$ROOT" },
"as": "el",
"cond": { "$ne": [ "$$el.k", "_id" ] }
}
}
}
}
}
])
or as suggested by 0zkr PM simply add a $project
pipeline step at the beginning:
db.collection.aggregate([
{ "$project": { "_id": 0 } },
{ "$addFields": {
"count": {
"$size": {
"$objectToArray": "$$ROOT"
}
}
} }
])