Reputation: 151
I have this schema on my node.js app. I'm using mongoose:
var todoSchema = new Schema({
task: String,
description: String,
date: Date,
status: String,
checklist: Boolean,
user: String
});
I want to get this result, so I can pass it into google chart and display it on chart:
[
{
"user": "A",
"detail" :
[
"open" : 3,
"progress" : 5,
"done" : 7
"archive" : 10
]
},
{
"user": "B",
"detail" :
[
"open" : 4,
"progress" : 9,
"done" : 14
"archive" : 12
]
}
]
But my query looks wrong:
Todo.find().distinct( "user", function(err, users){
Todo.find({"user": {"$in": users}}, function(err, todo){
if (err)
res.send(err);
var finalResult = [];
finalResult.push(todo);
res.send(finalResult);
//res.send(todo);
});
});
});
Anybody can help me, please? Really appreciated your help.
Upvotes: 1
Views: 733
Reputation: 103345
Use aggregation framework and run the following aggregation pipeline which uses two $group
and $project pipeline steps; the first one is to group your documents by the user
field and use the $cond
operator in the $sum
accumulator operator expression to evaluate the counts based on the status field. The second $group
pipeline step will add the detail
array by using the accumulator operator $push
that returns an array of expression values for each group. The last step $project
will modify the document fields by renaming the _id
field to user
:
var pipeline = [
{
"$group": {
"_id": "$user",
"open_count": {
"$sum": {
"$cond": [ { "$eq": [ "$status", "open" ] }, 1, 0 ]
}
},
"progress_count": {
"$sum": {
"$cond": [ { "$eq": [ "$status", "progress" ] }, 1, 0 ]
}
},
"done_count": {
"$sum": {
"$cond": [ { "$eq": [ "$status", "done" ] }, 1, 0 ]
}
},
"archive_count": {
"$sum": {
"$cond": [ { "$eq": [ "$status", "archive" ] }, 1, 0 ]
}
}
}
},
{
"$group": {
"_id": "$_id",
"detail": {
"$push": {
"open": "$open_count",
"progress": "$progress_count",
"done": "$done_count",
"archive": "$archive_count"
}
}
}
},
{
"$project": {
"_id": 0, "user": "$_id", "detail": 1
}
}
];
Todo.aggregate(pipeline, function (err, result){
if (err) res.send(err);
console.log(JSON.stringify(result, undefined, 4));
res.send(result);
})
Upvotes: 3
Reputation: 1668
This should work for you. Simply gets all of your todos.
Do not forget to return
when handling errors
Todo.find({}, function(err, todos){
if (err)
return res.send(err);
res.send(todos)
})
Upvotes: 0