Crear un sistema de notificaciones con MongoDB

pekpon

Buenas a todos!

Estoy montando una especie de red social y necesito implementar un sistema de notificaciones como facebook o MV: "pepe ha comentado una fotografia", "paco te ha agregado como amigo" o "XXX te ha citado en el post: YYY"

No tengo ni idea de por donde empezar. Uso Node.js y MongoDB y los esquemas que he encontrado por stackoverflow no me sirven de mucho.

Tengo diversos caminos pero no sé cual es el más óptimo. Alguien ha implementado algo parecido o sabe de alguna web donde lo describan bien. El lenguaje supongo que no importa, lo que necesito es la idea del concepto sobre como llevarlo a cabo.

Muchas gracias a todos!!!

PiradoIV

Yo alguna vez probé a hacer algo así, con una colección en plan events_log

{
from: ObjectId(...),
to: ObjectId(...),
event_type: "comment",
// cualquier otra cosa que necesites, un resumen del comentario,
// url del thumbnail de la fotografía, etc
}

El usuario que recibe las notificaciones puede tener en su documento una variable last_notification con el ObjectId de la última que leyó, y buscar las últimas sin leer.

Por otra parte, con la misma colección, puedes ver un registro de lo que ha hecho cada usuario y otro listado más, en plan registro de lo que han hecho los amigos de un usuario concreto.

1 respuesta
pekpon

#2 pensé lo mismo. Ahora, que crees que será más óptimo, un "registro" para cada aviso/usuario o uno general con un posible array y los Ids de los usuarios receptores, por ejemplo:

{
from: ObjectId(...),
to: [{ObjectId,read},{ObjectId,read},{ObjectId,read}],
event_type: "comment",
read: false
}

De este modo, si alguien comenta un post y quiero enviar un aviso a todos los usuarios que han comentado anteriormente, solo creo una notificacion y no 10( si han comentado 10 usuarios).

Me gusta más la opción read, en vez de una colección last_notification, no crees?

Gracias ;)

PiradoIV

Otra manera sería un array de suscriptores para cada publicación:

Pepito publica una foto, si Menganito y Juanito la comentan, se añaden a los suscriptores de las notificaciones de esa publicación.

Menganito vuelve a comentar, le mandamos una notificación individual a todos los demás suscriptores, con su read flag.

pekpon

Claro! entonces, cada vez que interactuas te subscribes a ese elemento. Cuando alguien realice alguna acción con dicho elemento, lo que debo hacer es enviar N notificaciones como ID's tenga el array de subscripciones que será el número de usuarios que están interactuando.

Si no quieres más publicaciones se borra el ID del array y dejas de recibir nada.

Si lo he entendido bien, esta es la idea, no? Me gusta! :D

1 respuesta
PiradoIV

#5 Sí, pero vamos, prueba la opción que más te guste xD

elkaoD

#1 lo que tú buscas se llama Redis/*MQ (RabbitMQ o alguna mierda de esas).

Sobre todo Redis.

Con el añadido de que no te sobrecargará el servidor de la BD, y es para lo que es.

2 2 respuestas
eisenfaust

Buscas precisamente lo de #7. +1 a redis/RabbitMQ.

Me parece que no eres consciente de la carga que supone un sistema de notificaciones.

1 respuesta
pekpon

#7 #8 pues lo he hecho con mongodb siguiendo las directrices de #5 y va como un tiro y realmente funciona.

Voy a mirarme de todos modos de que va el tal "redis/rabbitMQ" hasta ahora solo sabia de la existencia de redis, pero sin saber de que iba el tema.

Os cuento el procedimiento que he seguido:

1- El usuario comenta una noticia.
2- Buscamos si este usuario ya había comentado la notícia, de lo contrario, lo subscribimos.
3- Acto seguido creamos tantas notificaciones como usuarios hay subscritos, menos el usuario que escribe.
4- Los usuarios reciben sus notificaciones ya que están internamente relacionadas con hasMany belongsTo

Así de facil, que cambiará con reddis? Porque es tan necesario?
Mil gracias ;)

1 respuesta
Soltrac

Yo tb tengo curiosidad, Redis no deja de ser una base de datos NoSQL, que diferencia tiene con mongo?

2 respuestas
PiradoIV

#9 #10 Por aquí hay una comparativa de ese tipo de bases de datos:
http://kkovacs.eu/cassandra-vs-mongodb-vs-couchdb-vs-redis

En concreto Redis la recomiendan, por ejemplo para "Real-time communication"
Main point: Blazing fast

pekpon

tengo esto: http://stackoverflow.com/questions/5252577/how-much-faster-is-redis-than-mongodb

Redis es 2x más rápido escribiendo y 3x más rápido leyendo.

1 respuesta
Soltrac

#12 Sí pero hay q leer todo:

Numbers are going to be hard to find as the two are not quite in the same space. The general answer is that Redis 10 - 30% faster when the data set fits within working memory of a sing machine. Once that amount of data is exceeded, Redis fails. Mongo will slow down at an amount which depends on the type of load. For an insert only type of load one user recently reported a slowdown of 6 to 7 orders of magnitude (10,000 to 100,000 times) but that report also admitted that there were configuration issues, and that this was a very atypical working load. Normal read heavy loads anecdotally slow by about 10X when some of the data must be read from disk.

Conclusion: Redis will be faster but not by a whole lot.

PiradoIV

A ver, luego está el tema de... ¿qué tecnología te merece más la pena usar?, MediaVida tira con MySQL, tiene notificaciones y va genial... mejor released que frenarte infinito por no saber qué usar.

O tienes el éxito de ser el siguiente Whatsapp, o no vas a tener problemas de rendimiento.

PD: "Si funciona, no lo toques", etc... xD

1 respuesta
pekpon

#14 que grande: "Si funciona, no lo toques"

Pues funciona y de PM! De todos modos siempre hay que saber que existen otras tecnologias y saber de que van...como funcionan....

elkaoD

#10 por ejemplo http://redis.io/topics/pubsub

Cuanto más te metes con Redis más ves lo diferente que es con respecto a Mongo. No clasificaría a Redis como una NoSQL más.

1 respuesta
B

Que yo sepa redis almacena en memoria como memcache y pierdes los datos al reiniciarlo, nosql no, aunque creo que tb se puede configurar mongo para almacen en memoria y no en disco . Aviso que de nosql voy fatal y a lo mejor me equivoco.

1 respuesta
pekpon

#16 supongo que para hacer el timeline donde va ocurriendo lo que va pasando también recomendáis Redis, no? El problema es que lo tengo todo montado en Mongo xD

1 respuesta
elkaoD

#18 Mongo y Redis no son excluyentes, son complementarios.

#17 Redis almacena en memoria pero puedes hacer snapshots/journaling. Aún así, no lo recomendaba como motor de persistencia sino como MQ.

http://redis.io/topics/persistence

Toda la lógica de negocio de "reparto" de mensajes que habrá montado sobre backend a pelo, tirando sobre el NoSQL, Redis te la abstrae y te permite tenerlo como un servicio (facilidad de escalado: podrás en el futuro balancear, escalar web y no Redis, etc. etc.)

Y además es hip.

1
pekpon

Chicos de redis, tenéis idea de donde sacar info "detallada/explicada" sobre como manejar redis y el rabbitMQ en NODE.JS? Me está costando hacerme a la idea de como funciona todo esto, en las webs oficiales no me manejo demasiado bien...

Gracias a todos! ;)

S

Una vez que tengas el server de redis funcionando:

var redis = require('redis');
var redisClient = redis.createClient(config.redisPort, config.redisServer);
...
redisClient.set(token, val);
...
redisClient.get(token ,function(error,val){
  if(error) ...;
  
})
1 respuesta
pekpon

#21 Gracias, me has abierto el cielo! ;)

Usuarios habituales