Du kan enkelt aggregera resultatet istället för att välja en kartreducerande lösning:
-
Match
de poster där datumet är större än det angivna datumet. -
Group
baserat påbrand_id
fältet. -
Använd $addToSet operatör för att underhålla en
products
lista över unikaproduct_id
för varje grupp. -
Project
count
avproducts
array i varje tangent.
Kod:
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"}}}
])
Kommer till din kartreducerande lösning,
Det är ett sätt som mongodb kan anropa reduceringsfunktionen för varje grupp. Från dokumenten :
Du måste göra några ändringar på din map
,reduce
funktioner och lägg till en ny finalize
funktion:
- Du måste komma ihåg att när
mongodb
anroparreduce
funktionen för samma tangent mer än en gång skickas resultatet av föregående anrop som en ingång till reduceringsfunktionen, tillsammans med de andra värdena nästa gång reduceringsfunktionen anropas. - Första punkten, så du måste se till att indata till reduceringsfunktionen och returvärdet från reduceringsfunktionen är konstruerade på liknande sätt, så att logiken som skrivits inuti reduceringsfunktionen kan rymma bearbetning av dess eget returnerade värde i dess tidigare anrop.
- Eftersom vi inte skulle kunna hämta antalet distinkta värden när de anropas i batcher, kan vi skriva en
reduce
funktion som samlar de distinktaproduct_ids
för varje nyckel och skriv enfinalize
funktion som beräknar antalet av dessa unika värden.
Kod:
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;
}
}
)