Скажите, что ваша коллекция настроена на записи, подобные следующим:
> db.test_col.findOne()
{
"_id" : ObjectId("4f90ed994d2246dd7996e042"),
"statistics" : {
"20111206" : {
"CN" : {
"Beijing" : {
"cart" : 1,
"cart_users" : [
{
"oid" : "4EDD73938EAD0E5420000000"
}
],
"downloads" : {
"wmv" : {
"mid" : 1
}
},
"orders" : {
"wmv" : {
"mid" : 1
}
}
}
}
}
}
}
Вот команда, которая сгруппирует по странам, предоставит список городов и общее количество по стране. Это должно приблизить вас к тому, что вы пытались сделать:
db.runCommand({ mapreduce: "test_col",
map: function () {
var l0 = this.statistics,
date = Object.keySet(l0)[0],
l1 = l0[date],
country = Object.keySet(l1)[0],
l2 = l1[country],
city = Object.keySet(l2)[0],
data = l2[city];
emit(country, { date: date, city: city, data: data });
},
reduce: function (country, values) {
var r = { cities: [], count: 0 };
values.forEach(function (v) {
if (r.cities.indexOf(v.city) == -1) r.cities.push(v.city);
r.count++;
});
return r;
},
out: { reduce: "test_col_reduce" }
});
Вывод моих тестовых данных выглядит следующим образом:
> db.test_col_reduce.find()
{ "_id" : "AR", "value" : { "cities" : [ "San Juan", "Buenos Aires", "Cordoba", "Rosario" ], "count" : 18 } }
{ "_id" : "BZ", "value" : { "cities" : [ "Morico", "San Ignacio", "Corozal" ], "count" : 15 } }
{ "_id" : "CN", "value" : { "cities" : [ "Beijing", "Shanghai", "HongKong" ], "count" : 26 } }
{ "_id" : "US", "value" : { "cities" : [ "San Diego", "Los Angeles", "San Francisco", "New York" ], "count" : 27 } }