Marta
Marta

Reputation: 1162

Mongodb count() of internal array

I have the following MongoDB collection db.students:

/* 0 */
{
    "id" : "0000",
    "name" : "John"
    "subjects" : [
      {
        "professor" : "Smith",
        "day" : "Monday"  
      },
      {
        "professor" : "Smith",
        "day" : "Tuesday"  
      }
  ]
}

/* 1 */
{
    "id" : "0001",
    "name" : "Mike"
    "subjects" : [
      {
        "professor" : "Smith",
        "day" : "Monday"  
      }
    ]
}

I want to find the number of subjects for a given student. I have a query:

 db.students.find({'id':'0000'})

that will return the student document. How do I find the count for 'subjects'? Is it doable in a simple query?

Upvotes: 5

Views: 2109

Answers (3)

Siddhartha Chowdhury
Siddhartha Chowdhury

Reputation: 2732

Just another nice and simple aggregation solution:

db.students.aggregate([
    { $match : { 'id':'0000' } },
    { $project: {
        subjectsCount: { $cond: {
              if: { $isArray: "$subjects" },
              then: { $size: "$subjects" },
              else: 0
           }
        }
      }
    }
]).then(result => {
    // handle result
}).catch(err => {
    throw err;
});

Thanks!

Upvotes: 1

Mustafa Genç
Mustafa Genç

Reputation: 2579

If query will return just one element :

db.students.find({'id':'0000'})[0].subjects.length;

For multiple elements in cursor :

db.students.find({'id':'0000'}).forEach(function(doc) {
    print(doc.subjects.length);
})

Do not forget to check existence of subjects either in query or before check .length

Upvotes: 3

Anas
Anas

Reputation: 1861

You could use the aggregation framework

db.students.aggregate( 
    [ 
        { $match : {'_id': '0000'}}, 
        { $unwind : "$subjects" }, 
        { $group : { _id : null, number : { $sum : 1 } } } 
    ] 
);
  • The $match stage will filter based on the student's _id
  • The $unwind stage will deconstruct your subjects array to multiple documents
  • The $group stage is when the count is done. _id is null because you are doing the count for only one user and only need to count.

You will have a result like :

{ "result" : [ { "_id" : null, "number" : 187 } ], "ok" : 1 }

Upvotes: 3

Related Questions