MongoDB - симулировать объединение или подзапрос - PullRequest
12 голосов
/ 08 июля 2010

Я пытаюсь найти лучший способ структурировать свои данные в Mongo для имитации того, что будет простым соединением или подзапросом в SQL.

Скажем, у меня есть классический пример Users and Posts с пользователямив одной коллекции и сообщения в другой.Я хочу найти все сообщения пользователей, чей город "Лондон".

Я упростил вещи в этом вопросе, в моем реальном сценарии хранение сообщений в виде массива в пользовательском документе не будет работать, поскольку у меня постоянно вставляются тысячи «сообщений» на пользователя.

Может ли оператор Mongos $ in помочь здесь?Может ли $ in обрабатывать массив из 10 000 000 записей?

Ответы [ 3 ]

11 голосов
/ 08 июля 2010

Честно говоря, если вы не можете вписать «Сообщения» в «Пользователи», то у вас есть два варианта.

  1. Денормализация некоторых пользовательских данных внутри сообщений.Тогда вы можете искать только в одной коллекции.
  2. Выполните два запроса.(один для поиска пользователей, другой - для поиска сообщений)

Исходя из вашего вопроса, вы пытаетесь сделать № 2.

Теоретически вы можете создать список идентификаторов пользователей (или ссылки), а затем найти все сообщения, принадлежащие пользователю $in этого массива.Но очевидно, что этот подход ограничен.

Может ли $ in обрабатывать массив из 10 000 000 записей?

Посмотрите, планируете ли вы "запросить" свои сообщения для всехпользователи в наборе 10 000 000 пользователей вы уже прошли этап «запроса».Вы сами говорите, что у каждого пользователя есть тысячи сообщений, поэтому вы говорите о запросе «Пользователи с сообщениями, которые живут в Лондоне» , возвращающем 100 миллионов записей.

100 миллионовзаписи не являются запросами, это набор данных!

Если вы беспокоитесь о нарушении команды $in, тогда я настоятельно рекомендую использовать map / redu * .Mongo Map / Reduce создаст новую коллекцию для вас.Затем вы можете урезать или суммировать этот набор данных по своему усмотрению.

3 голосов
/ 08 июля 2010

$ in может обрабатывать 100 000 записей.Я никогда не пробовал 10 000 000 записей, но запрос (запрос также является документом) должен быть меньше 4 МБ (как и любой документ), поэтому 10 000 000 записей невозможно.

Почему вы не включаете пользователя и его город в коллекцию сообщений?Вы можете индексировать этот город, потому что вы можете индексировать свойства встроенных объектов.Вам больше не нужно имитировать объединение, потому что вы можете запрашивать сообщения в городах встроенных пользователей.

Это означает, что вам нужно обновлять сообщения, когда меняется город пользователя, но это случается не очень часто.Это обновление будет быстрым, если вы индексируете идентификатор пользователя в коллекции сообщений.

2 голосов
/ 08 июля 2010

У меня что-то похожее, но мои настройки ориентированы на "пользователей" и "сообщения".Я добавил ссылку на пользователя, вроде внешнего ключа.Я использовал сгенерированный «_id» из коллекции пользователей и сохранил его как ключ внутри «сообщений».Для каждого сообщения, которое отправляет пользователь, я сохраняю его в коллекции «messages».Вы должны прочитать о dbrefs , я думаю, это то, что вы ищете.

Вам нужно будет выполнить несколько запросов, но вы обязательно должны сделать это на стороне приложения.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...