Vous pouvez effectuer cette opération mapReduce.
D'abord le mappeur :
var mapper = function () {
if ( this.flag == true ) {
totalCount++;
} else {
totalCount = 0;
}
if ( totalCount != 0 ) {
emit (
counter,
{ _id: this._id, totalCount: totalCount }
);
} else {
counter++;
}
};
Qui conserve un décompte du nombre total de fois que le true
la valeur est vue dans le drapeau. Si ce nombre est supérieur à 1, nous émettons la valeur, contenant également le document _id
. Un autre compteur utilisé pour la clé est incrémenté lorsque le drapeau est false
, afin d'avoir une "clé" de regroupement pour les matchs.
Puis le réducteur :
var reducer = function ( key, values ) {
var result = { docs: [] };
values.forEach(function(value) {
result.docs.push(value._id);
result.totalCount = value.totalCount;
});
return result;
};
Pousse simplement le _id
valeurs sur un tableau de résultats avec le totalCount.
Exécutez ensuite :
db.people.mapReduce(
mapper,
reducer,
{
"out": { "inline": 1 },
"scope": {
"totalCount": 0,
"counter": 0
},
"sort": { "updated_at": 1 }
}
)
Donc avec le mapper
et reducer
fonctions, nous définissons ensuite les variables globales utilisées dans "scope" et passons le "sort" qui était requis sur updated_at
Rendez-vous. Ce qui donne le résultat :
{
"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,
}
Bien sûr, vous pouvez simplement ignorer le totalCount
variable et utilisez simplement la longueur du tableau, qui serait la même. Mais puisque vous voulez utiliser ce compteur de toute façon, il suffit de l'ajouter. Mais c'est le principe.
Alors oui, c'était un problème adapté à mapReduce, et maintenant vous avez un exemple.