Pregunta

Suponga que tiene un gran número de usuarios (M) y un gran número de documentos (N) y desea que cada usuario sea capaz de marcar cada documento como leído o no leído (al igual que cualquier sistema de correo electrónico). ¿Cuál es la mejor manera de representar esto en MongoDB? O cualquier otra base de datos documental?

Hay varias preguntas sobre stackoverflow hace esta pregunta para bases de datos relacionales, pero no vi ninguna de las recomendaciones para bases de datos documentales:

Cuál es el más de manera eficiente para recordar leer / no leído a través de múltiples artículos?

La implementación de un sistema eficiente de los comentarios "no leídos" contadores

Por lo general las respuestas implican una tabla que enumera todo lo que un usuario ha leído: (es decir tuplas de identificación del usuario, documento de identidad) con algunas posibles optimizaciones para una fecha de corte que permite margen de todo-como-leer para limpiar la base de datos y volver a empezar sabiendo que cualquier cosa antes de esa fecha se 'leer'.

Por lo tanto, los expertos MongoDB / NoSQL, lo que se acerca ha visto en la práctica a este problema y cómo se llevan a cabo?

¿Fue útil?

Solución

{
_id: messagePrefs_uniqueId,
type: 'prefs',
timestamp: unix_timestamp
ownerId: receipientId,
messageId: messageId,
read: true / false,
}

{
_id: message_uniqueId,
timestamp: unix_timestamp
type: 'message',
contents: 'this is the message',
senderId: senderId,
recipients: [receipientId1,receipientId2]
}

Digamos que tienes 3 mensajes que desea recuperar las preferencias para, usted puede conseguir a través de algo como:

db.messages.find({
messageId : { $in : [messageId1,messageId2,messageId3]},
ownerId: receipientId, 
type:'prefs'
})

Si todo lo que necesita es leído / no leído usted podría utilizar esto con capacidades upsert de MongoDB, por lo que no está creando de preferencias para cada mensaje a menos que el usuario realmente lo lee, entonces, básicamente, se crea las Preferencias objeto con su propia identificación única y upsert en MongoDB. Si desea más flexibilidad (como etiquetas dicen o carpetas) es probable que desee hacer el pref para cada destinatario del mensaje. Por ejemplo, podría añadir:

tags: ['inbox','tech stuff']

a las Preferencias objeto y después de obtener todos los de preferencias de todos los mensajes etiquetados con 'tecnología cosas' que iría algo como:

db.messages.find({type: 'prefs', ownerId: recipientId, tags: 'tech stuff'})

A continuación, puede utilizar los messageids que usted encuentra dentro de las Preferencias para consultar y encontrar todos los mensajes que corresponden:

db.messages.find((type:'message', _id: { $in : [array of messageIds from prefs]}})

Podría ser un poco difícil si usted quiere hacer algo como contar cuántos mensajes cada 'etiqueta' contiene de manera eficiente. Si se trata de sólo un puñado de etiquetas que sólo puede añadir .count() hasta el final de la consulta para cada consulta. Si se trata de cientos o miles continuación, te pueden hacer mejor con un mapa / reducir el script del lado del servidor o tal vez un objeto que realiza un seguimiento de los recuentos de mensajes por etiqueta por usuario.

Otros consejos

Si sólo está almacenando un valor booleano simple, como leído / no leído, otro método es una matriz incrustada en cada documento que contiene una lista de los usuarios que lo han leído.

{
  _id: 'document#42',
  ...
  read_by: ['user#83', 'user#2702']
}

A continuación, debería ser capaz de indexar ese campo, para hacer consultas rápidas para documentos de lectura por el usuario y el Documento de Usuarios-que-lectura.

db.documents.find({read_by: 'user#83'})

db.documents.find({_id: 'document#42}, {read_by: 1})

Sin embargo, me parece que estoy por lo general las consultas a todos los documentos que han no sido leído por un usuario en particular, y no puedo pensar en ninguna solución que pueda hacer uso del índice de este caso. Sospecho que no es posible hacer esto rápido sin tener ambas matrices read_by y unread_by, de modo que cada usuario se incluye en cada documento (o tabla de unión), pero que tendría un gran coste de almacenamiento.

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top