Можете лесно да обедините резултата, вместо да изберете решение за намаляване на картата:
-
Match
записите, където датата е по-голяма от равна на посочената дата. -
Group
въз основа наbrand_id
поле. -
Използвайте $addToSet оператор за поддържане на
products
списък с уникаленproduct_id
за всяка група. -
Project
count
отproducts
масив във всеки ключ.
Код:
db.collection.aggregate([
{$match:{"date":{$gte:new Date('2014-11-20')}}},
{$group:{"_id":"$brand_id","products":{$addToSet:"$product_id"}}},
{$project:{"_id":0,"brand_id":"$_id","distinct_prod":{$size:"$products"}}}
])
Стигаме до вашето решение за намаляване на картата,
Това е един от начините, по които mongodb може да извика функцията за намаляване за всяка група. От документи :
Трябва да направите някои промени във вашата map
,reduce
функции и добавете нов finalize
функция:
- Трябва да запомните, че когато
mongodb
извикваreduce
функция за същия ключ повече от веднъж, резултатът от предишното извикване се предава като вход към функцията за намаляване, заедно с другите стойности при следващото извикване на функцията за намаляване. - Първа точка, така че трябва да се уверите, че входът към функцията за намаляване и върнатата стойност от функцията за намаляване са конструирани по подобен начин, така че логиката, записана вътре във функцията за намаляване, да може да поеме обработката на нейната собствена върната стойност в нейните предишни извиквания.
- Тъй като не бихме могли да извлечем броя на отделните стойности, когато се извикват на партиди, това, което можем да направим, е да напишем
reduce
функция, която акумулира отделнитеproduct_ids
за всеки ключ и напишетеfinalize
функция, която изчислява броя на тези уникални стойности.
Код:
db.collection.mapReduce(
function() {
// emitting the same structure returned by the reduce function.
emit(this.brand_id, {"prod_id":[this.product_id]});
},
function(key, values) {
// the return value would be a list of unique product_ids.
var res = {"prod_id":[]};
for(var i=0;i<values.length;i++)
{
for(var j=0;j<values[i].prod_id.length;j++){
if(res.prod_id.indexOf(values[i].prod_id[j]) == -1){
res.prod_id.push(values[i].prod_id[j]);
}
}}
return res;
},
{
query: {date: {$gte: new Date('2014-11-20')}},
out: "example",
finalize: function(key, reducedValue){
// it returns just the count
return reducedValue.prod_id.length;
}
}
)