user1255808
user1255808

Reputation:

nodejs notification system

I'm doing a notification system for my website. A notification systeme like facebook. Or stackoverflow. I have 2 problems.

  1. How store in db ? I can store ALL notifications in the user document ? or in a document apart (because i think monogdb is limited for size in a document ?) Or, store intelligently ? (using inc, or a value (see: true/false) in db, with query sophisticated)

  2. How do for brought at the page ? For exemple, when i click in a link in my inbox for stackoverflow, i'm redirect to the page. But me, i have a system that is multipage for exemple: I have 100 friends. There are listed 30 per page. So when i click on the notification i can't redirect to the because it's impossible to know the good page (users can be removed).

Thank you very much ! And if you have another ideas, tell me. Thanks.

EDIT:

(sorry for my english, i'm french)

For the first problem, i realize that i have to wait the time comes to choose my structure. Because my notification is .. a little complicated, so advance to the feeling.

For the second, i solved the problem. I explain: (I take the exemple of friends because it's easy to undestand.) I stored my data like this:

{
  friends: [
    {_id: xxxxx, ts: xxxx},
    {_id: xxxxx, ts: xxxx}
  ]
}

Imagine i display all friends: 30 per page. The problems are:

So, i store like this:

{
  friends: {
    xxxx: {ts:xxx},
    xxxx: {ts:xxx}
  }
}

Know i can sort the document, with use skip and limit. So if i want a portion, i do not need to take all documents.

To know the page, i just do the number of < or > to the ts, i have for exemple 11 friends who are > to the ts of the friends that i want, and do a count for all friends (ex: 50 friends) with 50 and 11, i can guess the page.

Is this solution is good ? - i need a count - a query to know the number of > or < and i can take the page where is listed the friend, keeping the sort ts

You can don't understand why i use a count. I need because they are not store in the same docment.

2 EDIT:

The problem with this solution, is that i need to make query object and update object outside of the mongo query (ex: for do friends.xxxxxx: {$exists:true}

ps: And what advantages are to use ts instead of date for mongodb ? I'm using ts but i think i will store date, and no ts.

3 EDIT

I will do like Sammaye. Store in separate document. Take a look at: http://mongly.com/Multiple-Collections-Versus-Embedded-Documents/#1 and http://openmymind.net/2012/1/30/MongoDB-Embedded-Documents-vs-Multiple-Collections/

Upvotes: 1

Views: 1171

Answers (2)

Sammaye
Sammaye

Reputation: 43884

@Stennie make a pretty complete answer.

However recently I did a similar thing in PHP for my website. The first thing to understand is whether you are doing a notification system or a wall (the two are very different), it seems unclear to me and I am not sure what you mean by:

How do for brought at the page ? For exemple, when i click in a link in my inbox for stackoverflow, i'm redirect to the page. But me, i have a system that is multipage for exemple: I have 100 friends. There are listed 30 per page. So when i click on the notification i can't redirect to the because it's impossible to know the good page (users can be removed).

That is not very good English and is very confusing when I read it. If you can expand on that I am sure people can answer better.

For a notification system I found that a large collection of notification objects also worked. So I had a schema like:

{
    _id: {},
    to_user: ObjectId{},
    user_id: ObjectId{}, // Originating user
    custom_text: "has posted a new comment on your wall post",
    read: false,
    ts: MongoDate()
}

And this would literally be the document I have to produce notifications. Each time a user commits an action that generates a notification it writes a new row to the DB with to_user being populated each time with each user needing to be notified. As for multiple users commiting the same action I actually convert the user_id field in a list of OjbectId's so I can say:

Sam, Dan and Mike all commented on your wall post

I then query by ts storing the last ts that the user looked at in their row allowing me to do a range based query on the newest notifications each time. This works quite well for sharding and querying in my personal experience.

Hope it helps,

Upvotes: 3

Stennie
Stennie

Reputation: 65323

Whether to embed or link is a common question for data modelling in MongoDB. If your number of notifications is going to be unbounded, you are likely going to be better saving these in a separate collection.

The current 16Mb document limit actually isn't as much as an issue as some other considerations:

  • A performance issue you may encounter by including all notifications in a single document is that fast-growing documents may also need to be relocated in the database more frequently (see Padding Factor).

  • You may want to be applying multiple updates to a document (such as setting a "read" flag on notifications) in a very short period of time, which means more contention for updating the same document (see Atomic Operations).

In order to implement paging you can use limit() in combination with a range query or skip(). A range query (eg. based on an indexed notificationDate) will make more effective use of indexes and perform better than skip() as your collection grows.

Upvotes: 1

Related Questions