Можете да извършите тази операция mapReduce.
Първо картографът:
var mapper = function () {
if ( this.flag == true ) {
totalCount++;
} else {
totalCount = 0;
}
if ( totalCount != 0 ) {
emit (
counter,
{ _id: this._id, totalCount: totalCount }
);
} else {
counter++;
}
};
Което поддържа текущия брой на общите пъти, които true
стойността се вижда във флага. Ако този брой е повече от 1, тогава излъчваме стойността, също съдържаща документа _id
. Друг брояч, който се използва за ключа, се увеличава, когато флагът е false
, за да има "ключ" за групиране на съвпаденията.
След това редукторът:
var reducer = function ( key, values ) {
var result = { docs: [] };
values.forEach(function(value) {
result.docs.push(value._id);
result.totalCount = value.totalCount;
});
return result;
};
Просто натиска _id
стойности върху резултатен масив заедно с totalCount.
След това стартирайте:
db.people.mapReduce(
mapper,
reducer,
{
"out": { "inline": 1 },
"scope": {
"totalCount": 0,
"counter": 0
},
"sort": { "updated_at": 1 }
}
)
Така и с mapper
и reducer
функции, след това дефинираме глобалните променливи, използвани в „обхват“ и предаваме „сортирането“, което беше необходимо на updated_at
дати. Което дава резултата:
{
"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,
}
Разбира се, можете просто да пропуснете totalCount
променлива и просто използвайте дължината на масива, която ще бъде същата. Но тъй като така или иначе искате да използвате този брояч, той просто се добавя. Но това е принципът.
Така че да, това беше проблем, подходящ за mapReduce и сега имате пример.