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"});
精彩评论