これは、集約フレームワークでは実行できないことであり、このタイプの操作で使用できる現在のMongoDBメソッドはmapReduceのみです。
その理由は、集約フレームワークには、現在のドキュメント以外のパイプライン内の他のドキュメントを参照する方法がないためです。これは、実際には「グループ化」パイプラインステージにも当てはまります。これは、「キー」でグループ化されていても、個々のドキュメントを思いどおりに処理できないためです。
一方、MapReduceには、ここでやりたいことを実行できる1つの機能があり、集計に「直接」関連することさえありません。実際には、すべての段階で「グローバルスコープの変数」を持つことができます。そして、基本的に「最後のドキュメントを保存する」ための「変数」を持つことだけが、結果を達成するために必要なことです。
したがって、これは非常に単純なコードであり、実際には「削減」は必要ありません。
db.collection.mapReduce(
function () {
if (lastVal != null)
emit( this._id, this.val - lastVal );
lastVal = this.val;
},
function() {}, // mapper is not called
{
"scope": { "lastVal": null },
"out": { "inline": 1 }
}
)
これにより、次のような結果が得られます:
{
"results" : [
{
"_id" : ObjectId("54a425a99b8bcd6f73e2d662"),
"value" : 2
},
{
"_id" : ObjectId("54a425a99b8bcd6f73e2d663"),
"value" : 3
},
{
"_id" : ObjectId("54a425a99b8bcd6f73e2d664"),
"value" : 4
}
],
"timeMillis" : 3,
"counts" : {
"input" : 4,
"emit" : 3,
"reduce" : 0,
"output" : 3
},
"ok" : 1
}
これは、発行された_id
として「何かユニークなもの」を選択しているだけです。 これは実際には、異なるドキュメントの値の違いだけであるため、特定のものではなく値です。
グローバル変数は通常、これらのタイプの「ペアリング」集計または「現在の合計」の生成に対するソリューションです。現在、集約フレームワークはグローバル変数にアクセスできませんが、これがあれば便利かもしれません。 mapReduceフレームワークにはそれらが含まれているため、集約フレームワークでも使用できるようにする必要があると言っても過言ではありません。
今のところそうではないので、mapReduceを使い続けてください。