В моей базе данных есть коллекция, представляющая IP-адреса, полученные из разных источников. Образец которого выглядит так:
{ "_id" : ObjectId("4e71060444dce16174378b79"), "ip" : "xxx.xxx.xxx.xxx", "sources" : { "Source1" : NumberLong(52), "Source2" : NumberLong(7) } }
Каждый объект будет иметь один или несколько источников.
Моя цель - показать количество записей, сообщаемых каждым источником, не обязательно зная имена всех возможных источников (поскольку новые могут потенциально быть добавлены в любое время). Я попытался решить эту проблему с помощью функции карты карты, просто выдавая 1 для каждого ключа в исходном хеше каждого объекта, но, похоже, что-то не так с моим синтаксисом. Если я сделаю следующее:
var map_s = function(){
for(var source in this.sources) {
emit(source, 1);
}
}
var red_s = function(key, values){
var total = 0;
values.forEach(function(){
total++;
});
return total;
}
var op = db.addresses.mapReduce(map_s, red_s, {out: 'results'});
db.results.find().forEach(printjson);
Я получаю
{ "_id" : "Source1", "value" : 12 }
{ "_id" : "Source2", "value" : 230 }
{ "_id" : "Source3", "value" : 358 }
{ "_id" : "Source4", "value" : 398 }
{ "_id" : "Source5", "value" : 39 }
{ "_id" : "Source6", "value" : 420 }
{ "_id" : "Source7", "value" : 156 }
Что слишком мало для размера базы данных. Например, я получаю в оболочке следующее, если рассчитывать на определенный источник:
> db.addresses.count({"sources.Source4": {$exists: true}});
1260538
Где моя ошибка?