2011-12-09 3 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. 대화에 메시지에 dbref를 사용하십시오 (사용자 요청시 이전 범위를 선택할 수 있도록 메시지 시간 소인과이 필드를 색인화하십시오).
  3. 모든 대화마다 별도의 capped collection을 사용하십시오. 당신은 두 번 모든 메시지를 작성해야합니다

    • : 당신이 "conversation_"

결과처럼 만든다면 이름을 쉽게 찾을 수있을 것입니다. 하지만 별도의 컬렉션으로 정상입니다.

  • 대화를 표시하려면 natural sort order에있는 하나의 컬렉션에서 모든 데이터를 선택하는 것이 매우 빠릅니다.
  • 자물쇠가 채워진 컬렉션은 자동으로 마지막 메시지를 저장하고 오래된 메시지를 삭제합니다.
  • 기본 메시지 컬렉션을 쿼리하여 사용자 요청에 오래된 메시지를 표시 할 수 있습니다.
  • +0

    @SalvadorDali 엄청난 수의 컬렉션을 두려워 할 필요가 없습니다. 올바른 것을 선택하는 것은 매우 빠르며 그 수에 이론적 인 제한이 없습니다. 그러나 당신은 바로 그러한 많은 수의 콜렉션을 지원하는 것이 어려울 것입니다. 이제 대화 상에 추가 색인이있는 거대한 컬렉션을 사용하는 것이 좋습니다. 이 경우 두 가지 문제가 추가됩니다. 예전의 일부 대화는 이전 메시지없이로드되며 제한된 콜렉션에 색인을 포함하는 것은 좋지 않습니다. – lig

    +0

    다른 DB로 분리되는 경우 많은 수의 콜렉션을 다루는 것이 더 쉬울 수도 있습니다. 문서 크기로 말하기. 크기가 약 1MB 인 엄청난 양의 문서를 가지고있는 것도 좋지 않습니다. 드라이버 성능, 복제 및 샤딩 성능을 저하시키기 때문입니다. 개인적으로 나는 한 문서에 대화를 저장하지 않을 것입니다. 여러 가지 가능한 문제가 있습니다. 메시지 검색, 단일 메시지 공유 또는 복사 등. – lig

    +1

    4 년 후 ... 끔찍한 대답이었습니다 ... – lig