Reputation: 33
I am pretty new with MongoDB and Mongoose and stumbled over following problem: I have a collection with about 600 documents of this (shortened) format:
{
_id: ObjectId(<Integer>),
sA: [
{
age: {
value: <Integer>
}
}
]
}
The documents contain age values in the range from 0 to about 100, but not all values are represented. I want to output one single Object in the form of
{
labels: [<Integer>, <Integer>, ...],
data: [<Integer>, <Integer>, ...]
}
where labels is an array containing all age values of all documents. And data contains the number of times, that age value was found.
My questions are:
If so, is it also possible to fill the gaps inside the labels and data array? Lets say, the output looks like this:
{
labels: [0,1,2,6,9]
data: [1,17,4,5,3]
}
but I would like it to look like this:
{
labels: [0,1,2,3,4,5,6,7,8,9],
data: [1,17,4,0,0,0,5,0,0,3]
}
Until now I have not been able to archive this format neither with an aggregate- nor with mapReduce pipeline. Do I have to do this in two steps? Like output an sorted array and then use an Javascript function on the server to extract and fill the data and label array and fill the gaps before sending the object back to the client?
Thank you in advance!!
Upvotes: 2
Views: 654
Reputation: 6153
I believe this is what you are looking for:
db.collection.aggregate([
{ $unwind: "$sA" },
{ $group: {
_id: "$sA.age.value",
count: {$sum: 1}
} },
{ $sort: {
_id: 1
}},
{ $group: {
_id: null,
labels: {
$push: "$_id"
},
data: {
$push: "$count"
}
}}
]);
I don't believe filling in missing values is possible, though.
Upvotes: 2