U kunt deze mapReduce-bewerking uitvoeren.
Eerst de mapper:
var mapper = function () {
if ( this.flag == true ) {
totalCount++;
} else {
totalCount = 0;
}
if ( totalCount != 0 ) {
emit (
counter,
{ _id: this._id, totalCount: totalCount }
);
} else {
counter++;
}
};
Die een lopende telling bijhoudt van het totaal aantal keren dat de true
waarde wordt gezien in vlag. Als dat aantal meer dan 1 is, geven we de waarde uit, die ook het document _id
bevat . Een andere teller die voor de sleutel wordt gebruikt, wordt verhoogd wanneer de vlag false
is , om een groeperingssleutel te hebben voor de wedstrijden.
Dan de verkleiner:
var reducer = function ( key, values ) {
var result = { docs: [] };
values.forEach(function(value) {
result.docs.push(value._id);
result.totalCount = value.totalCount;
});
return result;
};
Druk gewoon op de _id
waarden in een resultatenarray samen met de totalCount.
Voer dan uit:
db.people.mapReduce(
mapper,
reducer,
{
"out": { "inline": 1 },
"scope": {
"totalCount": 0,
"counter": 0
},
"sort": { "updated_at": 1 }
}
)
Dus met de mapper
en reducer
functies, definiëren we vervolgens de globale variabelen die worden gebruikt in "scope" en geven de "sort" door die vereist was op updated_at
datums. Wat het resultaat geeft:
{
"results" : [
{
"_id" : 1,
"value" : {
"docs" : [
3,
4
],
"totalCount" : 2
}
},
{
"_id" : 2,
"value" : {
"docs" : [
7,
8,
5
],
"totalCount" : 3
}
}
],
"timeMillis" : 2,
"counts" : {
"input" : 7,
"emit" : 5,
"reduce" : 2,
"output" : 2
},
"ok" : 1,
}
Je kunt de totalCount
natuurlijk ook gewoon overslaan variabele en gebruik gewoon de arraylengte, die hetzelfde zou zijn. Maar aangezien je die teller toch wilt gebruiken, wordt hij gewoon toegevoegd. Maar dat is het principe.
Dus ja, dit was een probleem dat geschikt was voor mapReduce, en nu heb je een voorbeeld.