Если тебе нужно бращаться к данным которые являются суб-документом, то лучше не сувать все в один документ, а разбить по коллекциям. Поэтому лучше так:
users - юзеры
rooms - комнаты, содержит массив users - что является массивом id пользователей.
messages - сообщения.
notifications - разного рода оповещания пользователям. Например что их пригласили в комнату или в чат с другим пользователем.
Предположим такой пример документа messages:
{
_id: 32,
user: 16,
room: 64,
timestamp: ISODate("2015-10-20T11:43:18.915Z"),
data: 'hello world!'
}
Для переписки 1-1 я бы тоже создавал room.
Можно содержать также у room'а, время последнего сообщение.
Таким образом если кто-то пришел в чат и версия его кеша отличается, то клиент запросит у сервера данные недавней истории сообщений, также раскажет о времени в кеше.
Естественно сервер не должен высылать сразу всю историю, а должен слать только недавние скажем 32 сообщения. Далее если клиент продолжает скроллить, и ему нужно еще сообщений, то запросит еще 32.
Сортировка тут по времени, следственно просто запрашиваешь типо такого:
db.messages.find({
'room': 64,
'timestamp': {
$lt: ISODate("2015-10-20T11:56:07.516Z")
}
}).sort({ timestamp: 1 }).limit(32);
Вот так получишь последние 32 сообщения, до определенной даты.
Индексировать коллекции естественно нужно тоже как полагается.
Например messages индексируй так:
db.messages.ensureIndex({
'room': 1,
'timestamp': -1
});
Давай больше экспериментов, и начинай с попроще, не замудряй