Reputation: 5075
I have collection
[
{
data: {
height: 1,
width: 2
}
},{
data: {
height: 3,
width: 2
}
},{
data: {
height: 3,
width: 1
}
}
]
How can I count how many 1's and 3's in data.height and 1's and 2's in data.width? Basically I need result like
{
data: {
haight: {
"1": 1,
"3": 2
},
width: {
"1": 1,
"2": 2
}
}
}
Thanks
Upvotes: 1
Views: 108
Reputation: 2397
How can I count how many 1's and 3's in data.height and 1's and 2's in data.width?
It's possible to aggregate each value individually (as show in other answers). Alternatively, you can aggregate both values with a single command:
db.test.aggregate({$group: {_id: "$data.height", width: {$push: "$data.width"}, heightCount: {$sum: 1}}},
{$project: {height: {id: "$_id", count: "$heightCount"}, width: 1}},
{$unwind: "$width"},
{$group: {_id: "$width", widthCount: {$sum: 1}, height: {$addToSet: "$height"}}},
{$unwind: "$height"},
{$group: {_id: null, width: {$addToSet: {id: "$_id", count: "$widthCount"}}, height: {$addToSet: "$height"}}})
How can I count how many 1's and 3's in data.height and 1's and 2's in data.width?
If you only want to aggregate 1's and 3's in data.height and 1's and 2's in data.width, then you can put the following command at the beginning of the pipeline:
{$match: {$and: [{$or: [{"data.width": 1}, {"data.width": 2}]}, {$or: [{"data.height": 1}, {"data.height": 3}]}]}}
Upvotes: 0
Reputation: 5075
Well for now I got what I need with mapReduce and it's "scope" parameter
db.myCollection.mapReduce(
function(){
if( this.data.height in res.data.height === false ) res.data.height[this.data.height] = 0;
if( this.data.width in res.data.width === false ) res.data.width[this.data.width] = 0;
res.data.height[this.data.height]++;
res.data.width[this.data.width]++;
emit('id', 1);
},
function(){
return res;
},
{
out: {inline: 1},
scope: {
res: {
data:{
height: {},
width: {}
}
}
}
}
)
Upvotes: 1