1

I'm having a MongoDB collection which looks same as below document and I wanted to find only one field values count which presents within the embedded array object.

I tried below query to fetch the data but doesn't work

db.mycollection.find({'quizzes':{skill:'html'}}).pretty()

below is the mongo document structure with sample value. the structure is the same as my original document

{

"user": "values",

"date": "234-234-234-234",

"quizzes":[

   {

     "skill": "html",
     "score": "12"

}

]

}

From the above document, I wanted to fetch only the skill field values which present within quizzes array which is an embedded document. my output should be like

{
"html": 10,
"php": 20,
"C#": 15,
"java": 18,
.
.
.
.
.

}

2 Answers 2

3

You can use the distinct() method. The following query can get us the expected output:

db.mycollection.distinct("quizzes.skill");

For more information, please check https://docs.mongodb.com/manual/reference/method/db.collection.distinct/

Edit I: Calculating count of skills too

db.collection.aggregate([
    {
        $unwind:"$quizzes"
    },
    {
        $group:{
            "_id":"$quizzes.skill",
            "k":{
                $first:"$quizzes.skill"
            },
            "v":{
                $sum:1
            }
        }
    },
    {
        $project:{
            "_id":0
        }
    },
    {
        $group:{
            "_id":null,
            "data":{
                $push:"$$ROOT"
            }
        }
    },
    {
        $project:{
            "data":{
                $arrayToObject:"$data"
            }
        }
    },
    {
        $replaceRoot:{
            "newRoot":"$data"
        }
    }
]).pretty()

Data set:

{
    "_id" : ObjectId("5d66ad357d0ab652c42315f7"),
    "user" : "values",
    "date" : "234-234-234-234",
    "quizzes" : [
        {
            "skill" : "html",
            "score" : "12"
        },
        {
            "skill" : "css",
            "score" : "10"
        }
    ]
}
{
    "_id" : ObjectId("5d66ad357d0ab652c42315f8"),
    "user" : "values2",
    "date" : "234-234-234-234",
    "quizzes" : [
        {
            "skill" : "Java",
            "score" : "12"
        },
        {
            "skill" : "html",
            "score" : "10"
        }
    ]
}

Output:

{ "Java" : 1, "css" : 1, "html" : 2 }

Explanation: We are creating a key and value pair (k,v) where 'k' is the skill and 'v' is the count of skill occurrence. The reason behind taking field names as 'k' and 'v' is because $arrayToObject only takes these fields only. Later on, all keys and values are merged to prepare the final document.

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

5 Comments

@Sharma exactly that will only give you the exact distinct values. but I need values which are duplicate as well to get the count. ex: {'html':10, 'php': 15} like wise
@GopiP Updated answer
thanks it works charm. Do we have any even easy to do???? just asking for learning purpose
@GopiP As per your requirements, we did it that way. If you need a response like this: {"skills":[{"skill":"html":2},{"css":1},{"Java":1}]}, then it can be done easily.
oh thanks @Sharma, If possible can you please share the code too. So, that I could come to know that as well.
0

You can use aggregates to get the desired results.

db.myCollection.aggregate({ $group: { "skill": "$quizzes.skill","count":{ "$sum":1 }} })

1 Comment

when I run the mentioned query it gives below error The field 'skill' must be an accumulator object

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.