Mongodb limit in embedded document

I need to create a messaging system where a person can talk with many users. For example, I start talking with user2, user3 and user4, so any of them can see the whole conversation, and if the conversation is not private at any time, any of the participants can add any other person to the conversation.

Here is my idea how to do this. I use Mongo, and my idea is to use the dialog as an instance instead of a message.

The scheme is indicated as follows:

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

I see some pros for this approach - in a large database it will be easy to find messages for a specific conversation. - It will be easy to add people to the conversation.

but here is a problem for which I canโ€™t find a solution: the conversation gets too long (take skype as an example) and they donโ€™t show you the whole conversation, they show you a part and then show you additional messages. In other situations, skip, the limit resolves the matter, but how can I do it here?

If this is not possible, what suggestions do you have?

+7
source share
2 answers

MongoDB docs explain how to select a submenu of an array element.

 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 

You can use this technique only to select messages that are relevant to your user interface. However, I'm not sure if this is a good circuit design. You might want to separate the โ€œvisibleโ€ messages from the โ€œarchivedโ€ messages. This can make the request a little easier / faster.

+13
source

There are reservations if there are many messages in your conversation:

  • You will notice a significant decrease in performance for slicing message arrays, since mongodb will load all of them and cut the list before returning only to the driver.
  • There is currently a document size limit (16 MB) that can be achieved using this approach.

My suggestions:

  • Use two collections: one for conversations and one for messages.
  • Use dbref in conversation messages (index this field with the timestamp of the message to be able to select older ranges at the user's request).
  • For each conversation, additionally use the capped collection . It will be easy to find by name if you build it as "conversation _"

Result:

  • You will need to write all messages twice. But in separate collections that are normal.
  • If you want to show your conversation, you just need to select all the data from one collection in a natural sort order , which is very fast.
  • Your private collections will automatically save the latest posts and delete old ones.
  • You can display old messages in a user request by requesting a collection of basic messages.
+1
source

All Articles