2011-12-09 11 views
7

Necesito crear un sistema de mensajes, donde una persona pueda tener una conversación con muchos usuarios. Por ejemplo, empiezo a hablar con user2, user3 y user4, por lo que cualquiera de ellos puede ver toda la conversación, y si la conversación no es privada en algún momento, cualquiera de los participantes puede agregar a otra persona a la conversación.Límite mongodb en el documento incrustado

Aquí está mi idea de cómo hacer esto. Estoy usando Mongo y mi idea es usar el diálogo como una instancia en lugar de un mensaje.

El esquema se muestra como sigue:

{ 
_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 
    } 
] 
} 

puedo ver algunas de las ventajas de este enfoque - en una gran base de datos que será fácil de encontrar mensajes de una conversación particular. - será fácil agregar personas a la conversación.

pero aquí hay un problema, para el cual no puedo encontrar una solución: la conversación es demasiado larga (tome Skype como ejemplo) y no le muestran toda la conversación, le muestran una parte y luego te muestran mensajes adicionales. En otras situaciones omita, limit soluciona el caso, pero ¿cómo puedo hacer esto aquí?

Si esto no es posible, ¿qué sugerencias tiene?

Respuesta

13

The MongoDB docs explica cómo seleccionar un subrango de un elemento de matriz.

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 

Puede utilizar esta técnica solo para seleccionar los mensajes que son relevantes para su UI. Sin embargo, no estoy seguro de que este sea un buen diseño de esquema. Es posible que desee considerar separar los mensajes "visibles" de los mensajes "archivados". Puede hacer que la consulta sea un poco más fácil/rápida.

+0

No hay problema. Si mi respuesta lo ayudó con su problema, marque la respuesta como está seleccionada. Esto me dará puntos y hará que los usuarios sean más propensos a responder sus preguntas en el futuro :) – jmacinnes

+0

muy útil gracias! – webmaster

1

hay advertencias si su conversación tendrá muchos muchos mensajes:

  1. Usted notará la reducción significativa del rendimiento de corte de mensajes matrices como mongodb hará lo cargar todos ellos y cortará la lista antes del regreso a conductor sólo .
  2. Existe un límite de tamaño de documento (16 MB por ahora) que podría alcanzarse con este enfoque.

Mis sugerencias es:

  1. Uso dos colecciones: una para las conversaciones y el otro para los mensajes.
  2. Use dbref en los mensajes a la conversación (indexe este campo con la marca de tiempo del mensaje para poder seleccionar rangos más antiguos a petición del usuario).
  3. Uso adicional por separado capped collection para cada conversación. Será fácil de encontrar por su nombre si lo construye como "conversation_"

Resultado:

  • Usted tendrá que escribir todos los mensajes dos veces. Pero en colecciones separadas, lo cual es normal.
  • Cuando desee mostrar su conversación, necesitará simplemente seleccionar todos los datos de una colección en natural sort order que es muy rápido.
  • Sus colecciones con máscaras almacenarán automáticamente los últimos mensajes y eliminarán los viejos.
  • Puede mostrar mensajes más antiguos en la solicitud del usuario consultando la recopilación de mensajes principales.
+0

@SalvadorDali No necesita preocuparse por la gran cantidad de colecciones. Elegir el correcto es muy rápido y no hay un límite teórico para ese número. Pero tiene razón, será difícil respaldar una cantidad tan grande de colecciones. Ahora voy a sugerir utilizar una gran colección con tope y un índice adicional de conversación. En tal caso, habrá dos problemas adicionales: algunas conversaciones antiguas se cargarán sin mensajes previos y no es muy bueno tener un índice en la colección limitada. – lig

+0

Puede ser que sea más fácil tratar con un gran número de colecciones si se separarán en otro db. Hablando sobre el tamaño del documento. Incluso no es bueno tener un montón de documentos enormes que tengan un tamaño de aproximadamente 1 MB. Porque reducirá el rendimiento del controlador, la replicación y el rendimiento de fragmentación. Personalmente, nunca guardaré la conversación en un solo documento. Hay muchos problemas posibles: buscar mensajes, compartir o copiar un solo mensaje, etc. – lig

+1

4 años después ... qué terrible respuesta fue ... – lig

Cuestiones relacionadas