10秒間隔で物事を取得する場合は、少し計算して、これを集計で実行できます。
db.collection.aggregate([
{ "$group": {
"_id": {
"year": { "$year": "$created_at" },
"month":{ "$month": "$created_at" },
"day": { "$dayOfMonth": "$created_at" },
"hour": { "$hour": "$created_at" },
"minute": { "$minute": "$created_at" },
"second": { "$subtract": [
{ "$second": "$created_at" },
{ "$mod": [
{ "$second": "$created_at" },
10
]}
]}
},
"count": { "$sum" : 1 }
}}
])
つまり、1分間に10秒の間隔に分解され、わずかなmod10の計算で発生します。
それは合理的であり、骨材を使用しているので最速のランナーになると思います。示されているシーケンスが最初に一致した時間から10秒実行されていることが本当に必要な場合は、mapReduceを使用してプロセスを実行できます:
最初のマッパー:
var mapper = function () {
if ( this.created_at.getTime() > ( last_date + 10000 ) ) {
if ( last_date == 0 ) {
last_date = this.created_at.getTime();
} else {
last_date += 10000;
}
}
emit(
{
start: new Date( last_date ),
end: new Date( last_date + 10000 )
},
this.created_at
);
}
したがって、これは10秒間隔内で日付を発行し、最初の日付から開始して、範囲外の何かが見つかるたびに間隔を増やします
今、あなたはレデューサーが必要です:
var reducer = function (key, values) {
return values.length;
};
とてもシンプルです。渡された配列の長さを返すだけです。
mapReduceはそのように機能するため、複数の値を持たないものはすべてレデューサーに渡されないため、finalizeを使用してこれをクリーンアップします。
var finalize = function (key, value) {
if ( typeof(value) == "object" ) {
value = 1;
}
return value;
};
次に、それを実行して結果を取得します。マッパーで使用されるグローバル変数を渡す「スコープ」セクションに注意してください。
db.collection.mapReduce(
mapper,
reducer,
{
"out": { "inline": 1 },
"scope": { "last_date": 0 },
"finalize": finalize
}
)
それぞれのアプローチでわずかに異なる結果が得られる可能性がありますが、それがポイントです。実際に使用したいものによって異なります。
あなたのコメントを考慮すると、どちらかのステートメントからの出力を「検査」し、プログラムで「ギャップを埋める」ことができます。私は一般的にそのオプションを好みますが、それは私のプログラムではなく、このクエリから取得しようとしているシリーズの大きさもわかりません。
サーバー側では、「マッパー」にパッチを適用して、次のようなことを行うことができます。
var mapper = function () {
if ( this.created_at.getTime() > ( last_date + 10000 ) ) {
if ( last_date == 0 ) {
last_date = this.created_at.getTime();
} else {
// Patching for empty blocks
var times = Math.floor(
( this.created_at.getTime() - last_date ) / 10000
);
if ( times > 1 ) {
for ( var i=1; i < times; i++ ) {
last_date += 10000;
emit(
{
start: new Date( last_date ),
end: new Date( last_date + 10000 )
},
0
);
}
}
// End patch
last_date += 10000;
}
}
emit(
{
start: new Date( last_date ),
end: new Date( last_date + 10000 )
},
this.created_at
);
}