2013-02-17 16 views
5

gamesという概念をモデル化しようとしていますが、ここでteamsplayersがMongoDBで競合しています。MongoDB:サブ文書IDで検索するには?

私は2つのコレクション:playersgamesを持っています。

これはgamesの文書の仕組みです。私はこの選手が参加したすべてのゲームを見つけたいプレイヤーのIDを指定:

{ 
    "_id": { "$oid": "1" }, 
    "teams": [ 
     { 
      "players": [ 
       { 
        "player": { "$oid": "2" }, 
        "score": 500, 
       }, 
       { 
        "player": { "$oid": "3" }, 
        "score": 550, 
       } 
      ] 
     }, 
     { 
      "players": [ 
       { 
        "player": { "$oid": "4" }, 
        "score": 500, 
       }, 
       { 
        "player": { "$oid": "5" }, 
        "score": 550, 
       } 
      ] 
     } 
    ] 
} 

ここでタスクがあります。

私が試した:

db.games.find({ "teams.players.player._id": "2" }) 

はしかし、これは何も返しません。次のCoffeeScriptのクエリで

playerSchema = Schema 
    player: { type: Schema.ObjectId, ref: 'Player' } 
    score: { type: Number } 

teamSchema = Schema 
    players: [ playerSchema ] 

gameSchema = Schema 
    teams: [ teamSchema ] 

:ところで

、私は次のスキーマでマングースを使用してい

Game.find 'teams.players.player._id': playerId 

任意のプレイヤーIDの結果を返しませんいます。あなたの文書で

+0

あなたがスキーマをより良い方法で設計できると思うなら、私はいくつかの指針も手に入れたいと思います! –

+0

2つのチーム、または2つ以上のチームが必要ですか?私は2つのチームのためのまともな例を与えることができますが、より多くのチームは少し退屈であり、検索のための追加のフィールドが含まれています。 –

+0

それはちょうど2つのチームです。ありがとう! –

答えて

8

"players": [ 
      { 
       "player": { "$oid": "4" }, 
       "score": 500, 
      }, 
      { 
       "player": { "$oid": "5" }, 
       "score": 550, 
      } 
     ] 

playersの埋め込まれたコレクション内のplayerフィールドはBSON ID(すなわち、それはObjectId("4e208e070347a90001000008")ようになります)ですので、私はあなたがそうのようなクエリを構築すべきだと思う:

db.games.find({ "teams.players.player": ObjectId("2") }) 

注、私は_idを落としてきました - モンゴコンソールで働くように提供し、私は(_id部分をドロップ)コーヒークエリは同様であろうと思います。

+0

魅力のように、ありがとう! mongooseを使うと、自動的に文字列をオブジェクトID: 'Game.find 'teams.playersに変換するので、より簡単です。player ':playerId' –

1

私はこの例を自宅や離れたチームに限定するためにフィードバックを使用しました。 Mongoはリレーショナルデータベースではなく、関係を使用することはしばしばリレーショナルデータベースの考え方を示していることに注意してください。重複が鍵です。

ゲームから特定のプレーヤーのドキュメントへの参照ではなく、プレーヤーの名前が格納されています。私はこれが不変のユニークなインデックスであると仮定します。プレイヤーは、彼がプレイした各ゲームへの参照を含むゲーム配列を与えられています。これは、実際には、この配列を再度照会して読み込む必要があるため、実際にはかなり悪いことです。ここにも名前を格納する方が良いでしょうが、あなたの状況を知らないので、ゲームに不変の表現可能な名前があるかどうかはわかりません。

この基本的な考え方は、エラーチェック(ミドルウェアなど)によって改善する必要がありますが、私はあなたに任せます。

+0

お返事ありがとうございました!あなたが正しいです、私は間違いなく、長い間、リレーショナルデータを扱ってきました。あなたの命題に悩まされている2つのことがまだあります:1.他のドキュメントへの参照としてオブジェクトIDを使用することの問題は何ですか?名前は不変ではありませんが、IDは一意であることが保証されています。 2.私は、ゲームとプレイヤーとの関係が重複するという考えが嫌いです。私は本当にこのように矛盾を作成することを恐れています。私はあまりにもSQLですか? –

+0

1.それは高価です。 MongoDBにはJOINがないため、シミュレートするにはデータベースへの少なくとも2回のトリップが必要です。何兆ものレコードでは、SQLは低速になります。関連するデータを埋め込み、1つのドキュメントだけを引っ張るため、MongoDBはスケールされます。そうでなければ、同じチョークポイントに当たるでしょう。 2.はい、Mongoはあなたのデータを認識していないので、関係について知ることができず、検証やFKの完全性の概念もありません。矛盾が残っている場合は、SQLから移動しないでください.Sqlは、その一連の機能に驚くべきものです。 NoSQLは驚くべきスピードで多くの利便性を犠牲にしています。 –

+0

Roel、説明のおかげで。私はこれらの側面を考慮する。読書のヒントはありますか? –

関連する問題