Výsledek můžete snadno agregovat, místo abyste se rozhodli pro řešení redukující mapu:
-
Match
záznamy, kde je datum větší než rovno zadanému datu. -
Group
na základěbrand_id
pole. -
Použijte $addToSet operátor pro správu
products
seznam jedinečnýchproduct_id
pro každou skupinu. -
Project
count
zproducts
pole v každém klíči.
Kód:
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"}}}
])
Přicházíme k vašemu řešení pro redukci map,
To je jeden způsob, jak může mongodb vyvolat funkci snížení pro každou skupinu. Z dokumenty :
Musíte provést nějakou úpravu vaší map
,reduce
a přidejte nový finalize
funkce:
- To si musíte zapamatovat, když
mongodb
vyvoláreduce
funkce pro stejný klíč více než jednou, výsledek předchozího vyvolání je předán jako vstup do funkce snížení spolu s ostatními hodnotami při příštím vyvolání funkce snížení. - První bod:Musíte se tedy ujistit, že vstup do funkce snížení a návratová hodnota z funkce snížení jsou zkonstruovány podobně, takže logika zapsaná uvnitř funkce snížení se může přizpůsobit zpracování vlastní vrácené hodnoty v jejích předchozích voláních. li>
- Vzhledem k tomu, že bychom nebyli schopni získat počet odlišných hodnot při volání v dávkách, co můžeme udělat, je napsat
reduce
funkce, která shromažďuje odlišnáproduct_ids
pro každý klíč a napištefinalize
funkce, která vypočítá počet těchto jedinečných hodnot.
Kód:
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;
}
}
)