2011-09-12 13 views
2

私のデータベースにMongoDBを使用しています。私が現在取り組んでいるクエリでは、スキーマに不備がある可能性が明らかになりました。以下は私のコレクションの関連レイアウトです。 ゲームはチェスであるため、games.playersは2人のプレーヤーの配列であることに注意してください。Mongo複数のクエリまたはデータベースの正規化

users {_id, username, ...} 
games {_id, players[], ...} 
msgs {_id, username, gameid, time, msg} 

私は必要なデータがある:SQLデータベースで

All msgs for games which a user is in which is newer than a given timestamp. 

、私のクエリは、のようになります。

SELECT * FROM msgs WHERE time>=$time AND gameid IN 
    (SELECT _id FROM games WHERE players=$username); 

しかし、モンゴは、リレーショナルデータベースではありませんしたがって、サブクエリまたは結合はサポートされません。私は2つの解決策を見ています。 パフォーマンス面で効率的な方法は何でしょうか?

  1. 複数のクエリ
    • 選択ゲームユーザーがある、それまでにmsgs.gameid一致させるために$をで使用しています。
    • その他?
  2. 正規
    • くださいusers.gamesは、ユーザーがにあるすべてのゲームが含まれています。msgs.playersへ
    • コピーgames.playersをmsgs.gameid
    • などにより、

答えて

0

自分自身を「正規化」することができます。私は彼がメンバーであるゲームをリストするユーザーに配列を追加します。

ユーザー{_id、ユーザ名、ゲーム= {game1、game2、game3}}

は今、あなたが時間>時間$ {とgames._idユーザー "にある" MSGのでクエリを行うことができます。ゲーム}

各ユーザーのゲームリストを更新する必要があります。

+0

これはうまくいくが、それはusers.gamesが直線的に成長することを意味する。あなたは私に逆のことを考えさせ、games.playersをmsgsにコピーしました。それは時間とユーザーだけで一致します。 – Justin

+0

の場合、ユーザーごとに1人のレコードしかありません。 Msgsにはmsgごとにドキュメントがあるので、対処games.playerは各msgに大きなサブオブジェクトを配置します(さらに多くのデータ)。さらに、メッセージが送信された後にゲームのメンバーが変更されることがあります。 「ゲーム」を「ユーザー」の中に保存するということは、実際にゲーム内にプレーヤーを保存する必要はないということです。ユーザーの中の「ゲーム」フィールドには索引を付けることができます。 –

+0

これはチェスゲームのため、game.playerはサイズ2の定数です。これはあなたの推薦を変えるでしょうか?あなたのメソッドは2つのクエリを必要とすると思います。なぜなら、結合はないからですが、私だけが1を必要とします。 – Justin

2

私はMongoDBの比較的初心者ですが、私は自分自身が頻繁に2つのアプローチの組み合わせを使用しています。たとえば、ユーザー名は頻繁に表示されるクエリを簡素化するために複製されますが、情報を表示するだけでなく、複数のクエリを書き込む必要があるときは、時には2〜3レベルの深さで、$ inを使用して、与えられた操作のために働きます。

関連する問題