我现用nodejs+mongodb+mongoose. 我有个数据结构MyModel
{ depid:String, userid:String, username:String } 测试数据: {depid:‘a’,userid:‘1’,username:‘张1’} ,{depid:‘b’,userid:‘2’,username:‘张2’} ,{depid:‘a’,userid:‘3’,username:‘张3’} ,{depid:‘c’,userid:‘4’,username:‘张4’} ,{depid:‘c’,userid:‘5’,username:‘张5’} ,{depid:‘d’,userid:‘6’,username:‘张6’} 我想传入一个depid=‘a,c,b’ 值,根据depid获取分组数量,想要的结果: { depid:‘a’,count:2 ,depid:‘c’:count:2 ,depid:‘b’,count:1 } 请问该如何实现呢? 谢谢!
aggregate
大不了 mapreduce,但不要指望速度
具体怎么做,能讲讲吗。
用aggregate有一个问题,用$match无法匹配ObjectId
OutdoorApply.aggregate( [ {$match : {mobile:'18988889991'}} //这样可以,因为mobile字段是字符串 {$match : {outdoorid:'5463fda5b0687cad05c3c7c0'}} //这样就无法匹配 ,因为outdoorid是ObjectId // {$group:{ _id: {'outdoorid':'$outdoorid'}, count: { $sum: 1 }}} ], function (err, res) { if (err){ console.log('outdoorDao.getOutdoorApplyCount Error'+err); return callback(err,null); } return callback(err,res); } );
@jbasttdi .aggregate({$match:{’_id’:mongoose.Types.ObjectId(Id)}})
谢谢了,是的,是要转换的。
OutdoorApply.aggregate( [ {$match : {outdoorid: {$in:ids.map(function(id){return new ObjectId(id);})}}} ,{$group:{_id :"$outdoorid" ,count:{$sum:1}}} // ,{$group:{ _id: {'outdoorid':'$outdoorid'}, count: { $sum: 1 }}} ], function (err, res) { if (err){ console.log('outdoorDao.getOutdoorApplyCount Error'+err); return callback(err,null); } return callback(err,res); } );
总听到有人说aggredate效率不高,但不知有没有依据呢。 如果小数据,用这种方式也可以:
var q={'outdoorid':{$in:ids}}; var outdoors=OutdoorApply.find(q,'outdoorid',{},function(err,docs){ if(err){ console.log('outdoorDao.getOutdoorApplyCount Error'+err); return callback(err,null); } var uhash={}; docs.forEach(function(d){ if(!uhash[d.outdoorid]){ uhash[d.outdoorid]=0; } uhash[d.outdoorid]++; }); return callback(err,uhash); });