Since there's reluctance to show some sample documents in your collection, I've made some underlying assumptions on the structure of the documents in your collection based on the array in question.
Suppose your collection is composed of documents of this nature:
{
"category": {
"title": "home",
"name": "Fruits"
},
"name": "Apple"
},
{
"category": {
"title": "home",
"name": "Fruits"
},
"name": "Orange"
},
{
"category": {
"title": "home",
"name": "Vegetables"
},
"name": "Peas"
}
In order to get the desired result, you need to run an aggregation operation which is very efficient since it uses the native operators in MongoDB rather than doing async calls in a loop which suffers from performance issues.
Consider running the following pipeline:
var pipeline = [
{ "$match": { "category.title": "home" } },
{
"$group": {
"_id": {
"category": "$category.name",
"name": "$name"
},
"count": { "$sum": 1 }
}
},
{
"$group": {
"_id": "$_id.category",
"contents": {
"$push": {
"name": "$_id.name",
"count": "$count"
}
}
}
},
{
"$project": {
"_id": 0,
"heading": "$_id",
"contents": 1
}
}
];
Collection.aggregate(pipeline, function(err, result) {
console.log(JSON.stringify(result, null, 4));
});
Running the above aggregation operation on the assumed sample documents would yield the following result:
Sample Output
[
{
"heading": "Fruits",
"contents": [
{ "name": "Apple", "count": 1 },
{ "name": "Orange", "count": 1 }
]
},
{
"heading": "Vegetables",
"contents": [
{ "name": "Peas", "count": 1 }
]
}
]
UPDATE
From the comments trail, if you are using the collection from your previous question with the sample documents
/* 1 */
{
"_id" : ObjectId("58133a40c23d8b16b062e86a"),
"name" : "Tomatos",
"array" : [
{
"title" : "Vegetables"
}
],
"description" : "Vegitables are good to health"
}
/* 2 */
{
"_id" : ObjectId("58133a40c23d8b16b062e86b"),
"name" : "Apples",
"array" : [
{
"title" : "Fruits"
}
],
"description" : "Fruits are good to health, vegitables are also good to health"
}
/* 3 */
{
"_id" : ObjectId("58133a40c23d8b16b062e86c"),
"name" : "Apples",
"array" : [
{
"title" : "Vegetables-home-made"
}
],
"description" : "Fruits are good to health, vegitables are also good to health"
}
then consider running the following pipeline to get the desired results:
Collection.aggregate([
{ "$unwind": "$array" },
{
"$group": {
"_id": {
"category": "$array.title",
"name": "$name"
},
"count": { "$sum": 1 }
}
},
{
"$group": {
"_id": "$_id.category",
"contents": {
"$push": {
"name": "$_id.name",
"count": "$count"
}
}
}
},
{
"$project": {
"_id": 0,
"heading": "$_id",
"contents": 1
}
}
], function(err, result) {
console.log(JSON.stringify(result, null, 4));
});
Sample Output
/* 1 */
{
"contents" : [
{
"name" : "Apples",
"count" : 1
}
],
"heading" : "Vegetables-home-made"
}
/* 2 */
{
"contents" : [
{
"name" : "Apples",
"count" : 1
}
],
"heading" : "Fruits"
}
/* 3 */
{
"contents" : [
{
"name" : "Tomatos",
"count" : 1
}
],
"heading" : "Vegetables"
}
db.collection.find({ "category.title": "home" })? To provide a detailed answer, we would like to know the input as I believe this is just an aggregation operation where you want to output the counts from a field.