Need help with Mongodb best practices

I need to know what are the best practices for storing data in Mongodb.

I have a scenario where I need to develop a group chat.

Currently I have implemented the following structure:

Collection #1 - Users:

{ _id: "", name: "", email: ""}

Collection #2 - Groups:

{ _id: "", title: "", photo: "", "members": [{userId: ""}, {userId: ""}, {userId: ""}]}

Collection #3 - Messages:

{ _id: "", userId: "", messageText: ""}

I have created 3 different collections for this. Is this a good practice?

Or should I do something like:

Keep only one collection i.e: Users and put Groups and Messages under each user respectively?

Something like this:

{ 
	_id: "", 
	name: "", 
	email: "",
	groups: [
		{ 
			_id: "",
		 	title: "",
		 	photo: "",
		 	members: [{userId: ""}, {userId: ""}, {userId: ""}],
		 	messages: [
		 		{ _id: "", userId: "", messageText: ""},
		 		{ _id: "", userId: "", messageText: ""},
		 		{ _id: "", userId: "", messageText: ""},
		 	]
		},
		{ 
			_id: "",
		 	title: "",
		 	photo: "",
		 	members: [{userId: ""}, {userId: ""}, {userId: ""}],
		 	messages: [
		 		{ _id: "", userId: "", messageText: ""},
		 		{ _id: "", userId: "", messageText: ""},
		 		{ _id: "", userId: "", messageText: ""},
		 	]
		}
	]
}

One collection will be a headcahe once your users grows.

So do you recommend my original implication for this scenario?

I would also suggest using 3 collections instead of a single one. But I would change the structure a little bit:

Users: { _id: “”, name: “”, email: “”, groups: [ groupId0, …, groupIdN ]}
Groups: { _id: “”, title: “”, photo: “” }
Messages: { _id: “”, userId: “”, messageText: “”, groupId: “” }

Right. So we all agreed on 3 separate collections.

Now there is a confusing scenario, for “me” atleast:

What If I want to perform a deep search i.e on the groups listing screen, I want to type a keyword: “Mic”.

Now I want to search “Mic” in Groups+Users+Messages, A record from any source is appreciated.

How we handle such scenarios?

That’s when we combine them as an index that we push to elasticsearch depending on the needs of the search engine

In Atmosphere search for “socialize”. You will find everything there, you can get some inspiration or use as is. From what I see you need the structure of a forum with rooms rather than a chat. If you need a chat that looks like a chat things are far more complex since you might need to do user relationships, “who is typing”, delete a message (for me or everyone), aggregations by user, unread messages (keep track of who red a message in a room/chat).

"members": [{userId: ""}, {userId: ""}, {userId: ""}]

could be an array of user Ids instead of objects and you update it with $addToSet in order to avoid duplicates.
If you may have 100 - 1000 users in a group you should probably not have a members array at all. You could probably do an extra collection such as Conversations or Checkins and keep track of which user is in which Group.
E.g.

{  
   _id: "_"
    userId: "_",
    userName: "_",
    userEmail: "_",
    groupId: "_",
    unreadMessages: "_",
    // etc....
}

Then your group members will be a search in this collection rather than an aggregate between Groups and Users. Keep in mind that on large scale, storage is cheaper than querying in Mongo.