Możesz wykonać tę operację mapReduce.
Najpierw twórca map:
var mapper = function () {
if ( this.flag == true ) {
totalCount++;
} else {
totalCount = 0;
}
if ( totalCount != 0 ) {
emit (
counter,
{ _id: this._id, totalCount: totalCount }
);
} else {
counter++;
}
};
Co pozwala na bieżąco zliczać łączne czasy, w których true
wartość jest widoczna we fladze. Jeśli ta liczba jest większa niż 1, emitujemy wartość, zawierającą również dokument _id
. Inny licznik używany dla klucza jest zwiększany, gdy flaga ma wartość false
, aby mieć „klucz” grupujący mecze.
Następnie reduktor:
var reducer = function ( key, values ) {
var result = { docs: [] };
values.forEach(function(value) {
result.docs.push(value._id);
result.totalCount = value.totalCount;
});
return result;
};
Po prostu wypycha _id
wartości na tablicę wyników wraz z totalCount.
Następnie uruchom:
db.people.mapReduce(
mapper,
reducer,
{
"out": { "inline": 1 },
"scope": {
"totalCount": 0,
"counter": 0
},
"sort": { "updated_at": 1 }
}
)
Tak więc z mapper
i reducer
funkcje, następnie definiujemy zmienne globalne używane w "scope" i przekazujemy "sort", który był wymagany w updated_at
Daktyle. Co daje wynik:
{
"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,
}
Oczywiście możesz po prostu pominąć totalCount
zmiennej i po prostu użyj długości tablicy, która byłaby taka sama. Ale ponieważ i tak chcesz użyć tego licznika, jest on po prostu dodany. Ale to jest zasada.
Więc tak, to był problem pasujący do mapReduce, a teraz masz przykład.