Я могу предложить вам некоторое представление о том, что я сделал для имитации JOIN в MongoDB.
В подобных случаях я сохраняю идентификатор соответствующего пользователя (или нескольких пользователей) в данном объекте, например, в вашем объекте сообщения в коллекции сообщений.
(я не предлагаю, чтобы это была ваша схема, просто использую ее в качестве примера моего подхода)
{
_id: "msg1234",
from: "user1234",
to: "user5678",
subject: "This is the subject",
body: "This is the body"
}
Я бы запросил базу данных, чтобы получить все нужные мне сообщения, затем в своем приложении я бы повторил результаты и создал массив идентификаторов пользователей. Я бы отфильтровал этот массив, чтобы он был уникальным, а затем запросил бы базу данных во второй раз, используя оператор $in
, чтобы найти любого пользователя в данном массиве.
Затем в моем приложении я присоединю результаты к объекту.
Требуется два запроса к базе данных (или, возможно, больше, если вы хотите присоединиться к другим коллекциям), но это иллюстрирует то, что многие люди защищали в течение долгого времени: выполняйте свои СОЕДИНЕНИЯ на уровне приложений. Пусть база данных тратит свое время на запросы данных, а не на их обработку. Возможно, вы все равно сможете масштабировать свои серверы приложений быстрее и дешевле, чем база данных.
Я использую этот шаблон для создания каналов активности в реальном времени в своем приложении, и он работает безупречно и быстро. Я предпочитаю это денормализовать вещи, которые могут измениться, например, пользовательскую информацию, потому что при записи в базу данных MongoDB может потребоваться перезапись всего объекта, если новые данные не помещаются на место старых данных. Если бы мне нужно было переписать сотни (или тысячи) элементов активности в моей базе данных, это было бы катастрофой.
Кроме того, записи в MongoDB блокируются, поэтому, если произойдет сценарий, подобный тому, который я только что описал, все операции чтения и записи будут заблокированы до завершения операции записи. Я полагаю, что это будет решено в некоторой степени для серии 2.x, но все еще не будет идеальным.
Индексированные запросы, с другой стороны, очень быстрые, даже если вам нужно выполнить два из них, чтобы получить данные.