开发者

Grouping by values in an array

I have a set of records with the following structure:

{u'_id': ObjectId('4e60fc677fdfb50fc3000000'),
 u'columns': [
  {u'geodata_type': None,
   u'has_geodata': False,
   u'id': 1,
   u'is_available': True,
   u'is_key': False,
   u'name': u'NOMBRE',
   u'value': u'Martin'},
  {u'geodata_type': None,
   u'has_geodata': False,
   u'id': 2,
   u'is_available': True,
   u'is_key': False,
   u'name': u'EDAD',
   u'value': 12},
  {u'geodata_type': u'punto',
   u'has_geodata': True,
   u'id': 4,
   u'is_available': True,
   u'is_key': None,
   u'name': u'DIRECCION',
   u'value': u'humberto primero 2345'},
  {u'geodata_type': None,
   u'has_geodata': False,
   u'id': 5,
   u'is_available': True,
   u'is_key': False,
   u'name': u'BARRIO',
   u'value': u'centro'}],
 u'datasource_id': 1,
 u'map_empty': True
}

I pretend to group all the documents by some of those columns and to get counts by the given column name. The thing is, I don't find a proper way to set the key argument of the group operation to let mongo开发者_运维技巧 group the results properly.

Any suggestion?


You are trying to group on a value in an array and AFAIK group can only use a field. You can easily produce a set of column counts using map/reduce though:

Your mapper is where you'll do the grouping. Essentially for each column name, create a "group" (emit):

var mapper = function() {
    for (var k in this.columns) {
        emit(this.columns[k].name, {count:1} );
    }
}

In your reducer, aggregate the results for each group:

var reducer = function(key, values) {
    var sum = 0;
    values.forEach(function (item) {
        sum+=item.count;
    });
    return {count:sum};
}

Finally run the mapReduce operation:

var res = db.things.mapReduce(mapper, reducer, {out:"colCounts"});
0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜