あなたは間違いなくこれを行うことができます。一度に1つずつ質問に答えます:
1.マップフェーズに渡されるオブジェクトのセットをフィルタリングするmap-reduceとともにクエリを指定できます。 mongoシェルでは、これは次のようになります(m
と仮定) およびr
マッパー関数とレデューサー関数の名前です):
> db.coll.mapReduce(m, r, {query: {$or: [{"recently-voted": true}, {"hourly-score": {$gt: 0}}]}})
2.ステップ1では、過去1時間に少なくとも1回投票した(またはrecently-voted
)すべてのドキュメントでマッパーを使用できます。 trueに設定)、ただし、すべての投票が過去1時間に行われたわけではありません。したがって、マッパーでリストをフィルタリングし、カウントしたい票のみを発行する必要があります:
function m() {
var hour_ago = new Date() - 3600000;
this.votes.forEach(function (vote) {
if (vote.ts > hour_ago) {
emit(/* your key */, this.vote.a);
}
});
}
そして減らすために:
function r(key, values) {
var sum = 0;
values.forEach(function(value) { sum += value; });
return sum;
}
3.時間別スコアテーブルを更新するには、reduceOutput
を使用できます map-reduceのオプション。これにより、出力された値と、出力コレクションに以前に保存された値(存在する場合)の両方を使用してレデューサーが呼び出されます。そのパスの結果は、出力コレクションに保存されます。これは次のようになります:
> db.coll.mapReduce(m, r, {query: ..., out: {reduce: "output_coll"}})
出力を再削減することに加えて、merge
を使用できます これにより、出力コレクション内のドキュメントが新しく作成されたドキュメントで上書きされます(ただし、_id
を持つドキュメントはすべて残されます) _id
とは異なります s m-rジョブによって作成された)、replace
、これは事実上ドロップアンドクリエイト操作であり、デフォルトです。または、{inline: 1}
を使用します。 、結果をシェルまたはドライバーに直接返します。 {inline: 1}
を使用する場合は注意してください 、結果は1つのドキュメントで許可されているサイズ(最近のMongoDBリリースでは16MB)に収まる必要があります。
(4.)セカンダリ(「スレーブ」)でmap-reduceジョブを実行できますが、セカンダリは書き込みを受け入れることができないため(これにより、セカンダリになります)、インライン出力を使用する場合にのみこれを実行できます。