あなたsomeMap
が毎回変化しているので、私はすべてのドキュメントをスコアし、最高得点のものを返すこと以外の任意の代替が表示されません。このタイプの操作にどのような方法を採用しても、コレクション内のすべてのドキュメントを検討する必要があります。これは、スキャン速度が遅くなり、スキャンするコレクションが増えるにつれてますます高価になります。
map reduceの1つの問題は、各mongod
インスタンスが1つの同時マップ・リダクションのみを実行できることです。これは、シングルスレッドのjavascriptエンジンの制限です。複数のマップ縮小はインターリーブされますが、相互に同時に実行することはできません。これは、「リアルタイム」用途でマップリダクションに頼っている場合、つまり、Webページでマップを縮小してレンダリングする必要が生じた場合、最終的にはページの読み込み時間が許容できないほど遅くなるような制限が発生します。
すべてのドキュメントをアプリケーションにクエリし、アプリケーションコードでスコアリング、ソート、および制限を行うことで、この問題を回避できます。マップの縮小とは異なり、MongoDBのクエリは同時に実行できますが、もちろんこれは、アプリケーションサーバーが多くの作業を行う必要があることを意味します。
最後に、MongoDB 2.2のリリースが予定されている場合(数ヶ月以内)、map reduceの代わりに新しいaggregation frameworkを使用することができます。正しいパイプラインステップを生成するには、someMap
をマッサージする必要があります。
db.runCommand({aggregate: "foo",
pipeline: [
{$unwind: "$tags"},
{$project: {
tag1score: {$cond: [{$eq: ["$tags", "a"]}, 5, 0]},
tag2score: {$cond: [{$eq: ["$tags", "b"]}, 3, 0]}}
},
{$project: {score: {$add: ["$tag1score", "$tag2score"]}}},
{$group: {_id: "$_id", score: {$sum: "$score"}}},
{$sort: {score: -1}},
{$limit: 10}
]})
これは少し複雑で、クマは説明する:ここでは、これはsomeMap
が{"a": 5, "b": 2}
だったらどのように見えるかの例です
が
- まず、我々はタグ配列を「ほどく」は、そのよう「タグ」が配列からのタグの値であるスカラーであり、他のすべての文書フィールド(特に
_id
)が未解読要素ごとに複製されるパイプライン処理文書のステップに従う。
- 射影演算子を使用して、タグから名前付きスコアフィールドに変換します。
$cond
/$eq
式のそれぞれの意味は、( 'tag1score
の場合)'タグのフィールドidの値が 'a'の場合は5を返し、その値を新しいフィールドtag1score
に代入すると0を代入してください。この式は、someMap
の各タグ/スコアの組み合わせに対して繰り返されます。パイプラインのこの時点では、各ドキュメントはN tagNscore
のフィールドになりますが、最大でも1つの値は0ではありません。
- 次に、別の投影演算子を使用して
score
フィールドを作成します。このフィールドの値は、文書内のtagNscore
フィールドの合計です。
- 次に、ドキュメントを
_id
でグループ化し、各グループのすべてのドキュメントにわたって前の手順のscore
フィールドの値を合計します。
- 並べ替え
score
降順(つまり、最初に最大のスコア)
- トップ10のスコアに制限します。
私は、これは本質的にどのようにステップ3
に追加するには、ステップ2の突起の正しいセット、およびフィールドの正しいセットにsomeMap
を変換するために、読者への課題として残しておきますアプリケーションのコードやマップを減らすのと同じ一連のステップが実行されますが、マップの代わりにC++で完全に実装され、map reduceよりも速く並行して実行されます。すべてのドキュメントをアプリケーションに照会するのとは異なり、集約フレームワークはサーバー側のデータと連携してネットワークの負荷を軽減します。しかし、他の2つのアプローチと同様に、これは各ドキュメントを考慮する必要があり、すべてのスコアが計算された後でのみ結果セットを制限することができます。
'someMap'の内容は修正されていますか?または、時間の経過とともに変更されるか、クエリごとに変更されますか?ドキュメントが更新されているときにそれらが修正されている場合は、アプリケーション側のマッピングを行い、ドキュメントに直接スコアを挿入することになります(つまり、 'tags'に平行な配列にスカラーの 'score'属性)。 – dcrosta
someMapはアプリケーションによって生成されるため、既知です。私はドキュメントを更新していない、私はちょうど彼らの情報を読んで、それらを得点しています。 – Dharun
文書を書くアプリケーションの部分が 'someMap'に従ってスコアを挿入することは可能でしょうか? – dcrosta