2011-12-09 9 views
7

多くのユーザーと会話できるメッセージシステムを作成する必要があります。 たとえば、私はuser2、user3、user4と話し始めます。だから誰もが会話全体を見ることができます。会話がいつでもプライベートでない場合、参加者の誰かが他の人を会話に追加できます。埋め込み文書のmongodbの制限

これは私の考え方です。 私はMongoを使用しています。私の考えは、ダイアログの代わりにメッセージとしてインスタンスを使用することです。次のように

スキーマが表示されている:

{ 
_id : ...., // dialog Id 
'private' : 0 // is the conversation private 
'participants' : [1, 3, 5, 6], //people who are in the conversation 
'msgs' :[ 
    { 
    'mid' : ...// id of a message 
    'pid': 1, // person who wrote a message 
    'msg' : 'tafasd' //message 
    }, 
    .... 
    { 
    'mid' : ...// id of a message 
    'pid': 1, // person who wrote a message 
    'msg' : 'tafasd' //message 
    } 
] 
} 

私は、このアプローチ のためのいくつかの長所を見ることができます - 大きなデータベースには、いくつかの特定の会話のメッセージを見つけるのは簡単になります。 - 会話に人を簡単に追加できます。

しかし、ここで私は解決策を見つけることができません: 会話が長くなりすぎて(例としてskypeを取る)、彼らはあなたにすべての会話を表示していない、その後、彼らはあなたに追加のメッセージを表示しています。 他の状況では、limitをスキップすると問題は解決しますが、ここではどうすればよいですか?

これができない場合は、どのような提案がありますか?

答えて

13

The MongoDB docs配列要素の部分範囲を選択する方法を説明します。

db.dialogs.find({"_id": [dialogId]}, {msgs:{$slice: 5}}) // first 5 comments 
db.dialogs.find({"_id": [dialogId]}, {msgs:{$slice: -5}}) // last 5 comments 
db.dialogs.find({"_id": [dialogId]}, {msgs:{$slice: [20, 10]}}) // skip 20, limit 10 
db.dialogs.find({"_id": [dialogId]}, {msgs:{$slice: [-20, 10]}}) // 20 from end, limit 10 

この手法を使用して、自分のUIに関連するメッセージのみを選択できます。しかし、私はこれが良いスキーマ設計であるとは確信していません。 「目に見える」メッセージと「アーカイブされた」メッセージを区別することを検討することをお勧めします。クエリーをより簡単に/より速くするかもしれません。

+0

問題ありません。私の回答があなたの問題を解決する助けとなった場合は、答えを選択してください。これは私にポイントを与え、将来的にあなたの質問に答える可能性が高くなります:) – jmacinnes

+0

非常に感謝!!! – webmaster

1

は、あなたの会話が多く、多くのメッセージがあります場合の注意点があります:MongoDBのは、それらのすべてをロードしないだろうとあなたがメッセージの配列をスライスに大幅なパフォーマンスの低下がわかります

  1. をし、ドライバーに復帰する前にリストをスライスしますのみ。
  2. このアプローチではおそらく到達できる文書サイズの制限があります(現在は16MBです)。

私の提案は次のとおりです。

  1. は、2つのコレクションを使用します。メッセージのための会話用とその他を。
  2. 会話へのメッセージにdbrefを使用します(ユーザーの要求で古い範囲を選択できるようにメッセージのタイムスタンプとこのフィールドのインデックス付けを行います)。
  3. 追加の使用は、すべての会話に対して別々のcapped collectionです。あなたは二回、すべてのメッセージを記述する必要があります

    • :あなたは「conversation_」

結果のようにそれを構築する場合は、名前でそれを見つけることは容易になります。しかし、別のコレクションには正常です。

  • あなたの会話を表示するには、非常に速いnatural sort orderの1つのコレクションからすべてのデータを選択するだけで済みます。
  • あなたのキャップ付きコレクションは自動的に最後のメッセージを保存し、古いものを削除します。
  • メインメッセージコレクションを照会すると、ユーザーの要求に古いメッセージが表示されることがあります。
  • +0

    @SalvadorDaliコレクションの膨大な数を恐れる必要はありません。適切なものを選択することは非常に高速であり、その数には理論上の制限はありません。しかし、そうした膨大な数のコレクションをサポートするのは難しいでしょう。今では、会話にインデックスを追加して1つの大きなキャップ付きコレクションを使用するように提案します。このような場合には、2つの追加の問題があります。以前のメッセージがなくても古い会話が読み込まれ、キャップ付きのコレクションにインデックスを持たせることはあまり良くありません。 – lig

    +0

    別のデータベースに分かれていれば、多数のコレクションを扱う方が簡単かもしれません。 文書のサイズについて話す。サイズが約1MBの巨大な文書がたくさんあるのは良くありません。ドライバのパフォーマンス、レプリケーションおよびシャーディングのパフォーマンスが低下するためです。個人的に私は決して1つの文書に会話を保存しません。メッセージの検索、単一のメッセージの共有やコピーなど多くの可能性のある問題があります。 – lig

    +1

    4年後...恐ろしい答えです... – lig

    関連する問題