1

私は現在、DBから新製品のランダムサンプリングを取得したいMongoDBのプロジェクトに取り組んでいます。しかし、私の問題はMongoDB固有のものではなく、データベースに関する一般的な質問だと思います。

シナリオ:

製品のコレクション(またはテーブル)があるとしましょう。また、ユーザーのコレクション(またはテーブル)もあります。ユーザーがログインするたびに、10個の製品が表示されます。これらの製品は、コレクション/テーブルからランダムに選択されます。簡単ですが、ユーザーがログインするたびに、これまでに見たことのない10個の製品を提示する必要があります。この問題を解決するために私が考えることができる2つの明白な方法は次のとおりです。

  1. すべてのユーザーは、すべての製品の独自のプライベートリストから始めます。これらの製品のいずれかを入手するたびに、その製品はプライベートリストから削除されます。その結果、次にこの以前にトリミングされたリストから製品が選択されたときに、新しいアイテムのみがすでに含まれています。

  2. すべてのユーザーは、以前に表示された製品のプライベートリストを持っています。ユーザーがログインすると、マスターリストからランダムに10個の商品を選択し、それぞれのIDを以前に表示した商品のリストと比較します。アイテムが以前に表示したリストに表示された場合、アプリケーションはこれを破棄して新しい商品を選択します、そして10個の新しいアイテムができるまで繰り返し、次にそれを以前に表示したリストに追加します。

#1の問題は、それが途方もない無駄のように見えることです。基本的に、n人のユーザーのリストデータを複製することになります。また、システムへの新しいアイテムの削除/追加は、すべてのユーザーを反復処理する必要があるため、悪夢になります。#2の方が望ましいようですが、問題もあります。10個の新製品を保証するために、DBに対して多くの余分で不要な呼び出しを行うことになります。ユーザーがより多くの製品を経験するにつれて、選択できる新しい製品が少なくなるため、1つを捨てて、DBから新しい製品を入手しなければならない可能性が大幅に高まります。

別の解決策はありますか?私の最初のそして主要な関心事はパフォーマンスです。パフォーマンスを最適化するために、ディスク容量を放棄します。

4

3 に答える 3

0

これらの2つの方法は、プライマリメモリとセカンダリメモリの両方を完全に浪費します。今まで見たことのない商品を2つ見せたいのですが、これは本当に必見ですか?あなたがたくさんの製品を持っているならば、10のランダムなものはユニークである可能性が高いです。

3。MySQLほど簡単ではありませんが、1と2よりも複雑ではありませんが、10個のランダムな製品をリストできます。

于 2012-11-21T16:54:05.163 に答える
0

これを行うにはどうすればよいでしょうか:prodUser製品の ID と customersID (これらの製品を見た人) のリストだけを持つコレクションを作成します。

{
  prodID : 1,
  userID : []
}

顧客がログインすると、そのユーザーに割り当てられていない 10 個の prodID が見つかります

db.prodUser.find({
  userID : {
    $nin : [yourUser]
  }
})

(何らかの理由で $not が機能していません :-(。その理由を理解する時間がありません。よろしければ、お知らせください。)その人に製品を見せた後、彼の prodUser コレクションを更新できます。軽減するにはmongos はランダムな要素を見つけることができません - 要素をランダムに挿入して、最初の 10 個を見つけることができます。

すべてが非常に高速に動作するはずです。

于 2012-11-22T02:51:48.620 に答える
0

ID のシーケンスがどれだけランダムか気にしない場合は、次のようにすることができます。

製品 ID と連続した整数の代理キー列だけの単一のランダム化されたテーブルを作成します。最初のログイン時にリスト内のランダムなポイントから各顧客を開始し、そのキーで順序付けされたリストを循環します。最後まで来たらまた上から。

顧客レコードには、最後に見た製品の単一の値 (実際の ID ではなく、ランダム化されたリストからの代理) が含まれます。次に、ログイン時に次の 10 を取得し、顧客に対して 1 つの更新を行います。もちろん、それは本当にランダムではありません。しかし、この種のテーブルシード戦略は、より単純な疑似乱数ジェネレーターの多くがどのように機能するかです。

私が目にする唯一の問題は、ユーザーがログインするよりも製品リストが急速に成長する場合です。そうすると、開始した場所の前に表示されたリストの部分が表示されなくなります。それでも、多数の製品リストと非常にアクティブなユーザーの場合、見たものすべてを保存するよりもはるかに優れたスケーリングが必要です。したがって、一連の疑似乱数シーケンスで製品が表示されることが重要でない場合は、これが適している可能性があります。

編集:

彼らが始めた最初のレコードも保存した場合、見たすべてのもののリストを生成することができます. その値と最後に表示された値の間のすべてになります。

于 2012-11-21T18:18:06.077 に答える