5

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?

3 Answers 3

3

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

Sign up to request clarification or add additional context in comments.

Comments

3

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 }

Comments

1

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!

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.