7

1 人が多くのユーザーと会話できるメッセージ システムを作成する必要があります。たとえば、user2、user3、user4 と話し始めると、誰でも会話全体を見ることができ、会話がいつでも非公開でない場合、参加者は他の人を会話に追加できます。

これを行う方法は次のとおりです。私は 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
  }
]
}

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

しかし、ここに解決策が見つからない問題があります。会話が長くなりすぎて(スカイプを例にとります)、すべての会話が表示されず、一部が表示され、その後表示されます追加のメッセージ。他の状況では、スキップ、制限によってケースが解決されますが、ここでこれを行うにはどうすればよいですか?

これが不可能な場合、どのような提案がありますか?

4

2 に答える 2

16

MongoDB のドキュメントでは、配列要素の部分範囲を選択する方法について説明しています。

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 に関連するメッセージのみを選択できます。ただし、これが適切なスキーマ設計であるかどうかはわかりません。「アーカイブされた」メッセージから「表示される」メッセージを分離することを検討することをお勧めします。クエリが少し簡単/高速になる可能性があります。

于 2011-12-09T22:36:06.527 に答える
3

会話に多数のメッセージが含まれる場合は、注意事項があります。

  1. mongodb はメッセージ配列をすべてロードし、ドライバーのみに戻る前にリストをスライスするため、メッセージ配列をスライスするとパフォーマンスが大幅に低下することに気付くでしょう。
  2. このアプローチでは、ドキュメント サイズの制限 (現時点では 16MB) に達する可能性があります。

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

  1. 2 つのコレクションを使用します。1 つは会話用、もう 1 つはメッセージ用です。
  2. メッセージで dbref を使用して対話します (このフィールドにメッセージのタイムスタンプをインデックス付けして、ユーザーの要求に応じて古い範囲を選択できるようにします)。
  3. 会話ごとに別の上限付きコレクションを追加で使用します。「conversation_」のようにビルドすると、名前で見つけやすくなります。

結果:

  • すべてのメッセージを 2 回書き込む必要があります。しかし、通常の別のコレクションに。
  • 会話を表示したい場合は、1 つのコレクションからすべてのデータを自然な並べ替え順序で選択するだけで済みます。これは非常に高速です。
  • 上限のあるコレクションは、最後のメッセージを自動的に保存し、古いメッセージを削除します。
  • メイン メッセージ コレクションを照会することにより、ユーザー リクエストで古いメッセージを表示できます。
于 2011-12-12T11:34:31.200 に答える