Usuario y Notificaciones: Mejor forma de modelarlo

56 views
Skip to first unread message

Fernando

unread,
Jan 9, 2014, 2:57:06 PM1/9/14
to mongod...@googlegroups.com
Hola a todos!
con mi equipo de desarrollo estamos comenzando a utilizar mongoDB y nos hemos encontrado con un problema, que desde un punto de vista relacional es simple de solucionar, 
pero en mongo se me esta haciendo difícil decidir la forma en la que deberíamos guardar la información, pensando en como vamos a recuperar y actualizar la información.
En este caso son los usuarios y sus notificaciones.
La forma que utilizamos es la siguiente : 

usuario { 
  username: "fbenavides",
  notifications: [
     { texto: "texto notificacion",
       visto: true },
     { texot: "texto notificacion",
       visto: false }
  ]
}

Pero se complica bastante al momento que tenemos que obtener todas las notificaciones que tengan "false" en "visto".
Y eso me ha llevado a pensar que , derrepente en este caso, necesitamos crear una collection de notificaciones, donde se guarde el _id del usuario.

Alguien sabe cual es la mejor forma de modelarlo? 
Derrepente hay una opción para hacer el query sin necesidad de jalar todas las notificaciones y filtrar dentro de la aplicación las que no se han visto. ( el mismo problema sucede cuando queremos actualizar las notificaciones de visto: false a visto: true )

Les agradezco de antemano la ayuda,
Saludos

Jorge Puente Sarrín

unread,
Jan 10, 2014, 1:08:12 AM1/10/14
to mongod...@googlegroups.com
Hola Fernando,

De mi consideración, el modelo que tienes es un buen ejemplo para decidir no embeber documentos, sin embargo asumiendo que quisieras continuar con ello hay dos formas "factibles" para hacer las lecturas:

Primero, usar el operador de proyección $elemMatch pero sabiendo que sólo te retornará el primer elemento del array que coincida con la condición:
> db.users.find({username: "fbenavides"},
                {notifications: {$elemMatch: {visto: false}}})
{
        "_id" : ObjectId("52cf813c59a66e7bd879539c"),
        "notifications" : [
                {
                        "texto" : "texto notificacion",
                        "visto" : false
                }
        ]
}

Segundo, usar Aggregation Framework haciendo exactamente lo que necesitas pero teniendo un costo en el rendimiento:
> db.users.aggregate([
    {$match: {username: "fbenavides"}},
    {$unwind: "$notifications"},
    {$match: {"notifications.visto": false}},
    {$group: {_id: "$_id", notifications: {$push: "$notifications"}}}])
{
        "result" : [
                {
                        "_id" : ObjectId("52cf813c59a66e7bd879539c"),
                        "notifications" : [
                                {
                                        "texto" : "texto notificacion",
                                        "visto" : false
                                },
                                {
                                        "texto" : "otro",
                                        "visto" : false
                                },
                                {
                                        "texto" : "otro",
                                        "visto" : false
                                }
                        ]
                }
        ],
        "ok" : 1
}

Entonces para este caso en particular, de hecho preferiría usar documentos vinculados en dos colecciones distintas, suena razonable y funcionaría mucho mejor.

Hay algo más, manteniendo tu modelo, las notificaciones se incrementarán bastante haciendo que eventualmente superes el límite de 16MB por documento. A menos que desees usar algo que en el lanzamiento de la versión 2.4 llamaron "arrays con tope": http://docs.mongodb.org/manual/tutorial/limit-number-of-elements-in-updated-array/

Este puede ser un buen tema para hablar el sábado en el hangout. Espero que esto sirva.

Saludos.


2014/1/9 Fernando <fbenavi...@gmail.com>

--
Has recibido este mensaje porque estás suscrito al grupo "MongoDB Perú" de Grupos de Google.
Para anular la suscripción a este grupo y dejar de recibir sus correos electrónicos, envía un correo electrónico a mongodb-lima...@googlegroups.com.
Para publicar una entrada en este grupo, envía un correo electrónico a mongod...@googlegroups.com.
Visita este grupo en http://groups.google.com/group/mongodb-lima.
Para ver este debate en la Web, visita https://groups.google.com/d/msgid/mongodb-lima/f9b59e60-f735-49d2-ab2f-2448e81a1291%40googlegroups.com.
Para obtener más opciones, visita https://groups.google.com/groups/opt_out.



--
Jorge Puente Sarrín.

Renzo Ludeña

unread,
Jan 10, 2014, 10:14:03 AM1/10/14
to mongod...@googlegroups.com
yo tenia una duda similiar si vas a darle un mantenimiento como notifications como editar eliminar hacer busquedas por algun rango de fecha no se, seria mejor poner en una coleccion aparte pero si solo vas a listar pero sin ordenamiento y cambiar solamente el flag a true creo que mejor embeber


Fernando

unread,
Jan 10, 2014, 12:08:52 PM1/10/14
to mongod...@googlegroups.com
Gracias Jorge por tan detallada respuesta, creo que en este caso usaremos colecciones separadas.
Y tal vez debería documentarme más para poder usar $elemMatch y Aggregation Framework en algún otro problema.
Saludos!

Fernando

unread,
Jan 10, 2014, 12:11:00 PM1/10/14
to mongod...@googlegroups.com
Gracias mobius! Sí, hemos decidido tenerlos en colecciones separadas, parece que es la forma más óptima.
Saludos!
Reply all
Reply to author
Forward
0 new messages