Du kan gøre dette kortReducer operation.
Først kortlæggeren:
var mapper = function () {
if ( this.flag == true ) {
totalCount++;
} else {
totalCount = 0;
}
if ( totalCount != 0 ) {
emit (
counter,
{ _id: this._id, totalCount: totalCount }
);
} else {
counter++;
}
};
Som holder en løbende optælling af det samlede antal gange, som true
værdi ses i flag. Hvis tallet er mere end 1, udsender vi værdien, der også indeholder dokumentet _id
. En anden tæller, som bruges til nøglen, øges, når flaget er false
, for at have en gruppering "nøgle" til kampene.
Derefter reducereren:
var reducer = function ( key, values ) {
var result = { docs: [] };
values.forEach(function(value) {
result.docs.push(value._id);
result.totalCount = value.totalCount;
});
return result;
};
Du skal blot trykke på _id
værdier på et resultatarray sammen med totalCount.
Kør derefter:
db.people.mapReduce(
mapper,
reducer,
{
"out": { "inline": 1 },
"scope": {
"totalCount": 0,
"counter": 0
},
"sort": { "updated_at": 1 }
}
)
Så med mapper
og reducer
funktioner, definerer vi derefter de globale variabler, der bruges i "scope" og sender den "sort", der var påkrævet på updated_at
datoer. Hvilket giver resultatet:
{
"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,
}
Selvfølgelig kan du bare springe totalCount
over variabel og brug bare array-længden, som ville være den samme. Men da du alligevel vil bruge den tæller, er den bare tilføjet. Men det er princippet.
Så ja, dette var et problem egnet til mapReduce, og nu har du et eksempel.