Как выполнить эквивалент SQL Join в MongoDB?
Например, скажем, у вас есть две коллекции (пользователи и комментарии), и я хочу получить все комментарии с pid = 444 вместе с информацией о пользователях для каждой.
comments
{ uid:12345, pid:444, comment="blah" }
{ uid:12345, pid:888, comment="asdf" }
{ uid:99999, pid:444, comment="qwer" }
users
{ uid:12345, name:"john" }
{ uid:99999, name:"mia" }
Есть ли способ получить все комментарии с определенным полем (например, ... find ({pid: 444})) и информацию о пользователе, связанную с каждым комментарием, за один раз?
В данный момент я сначала получаю комментарии, которые соответствуют моим критериям, затем вычисляю все uid в этом наборе результатов, получаю пользовательские объекты и объединяю их с результатами комментария. Похоже, я делаю это неправильно.
Ответы:
Начиная с версии 3.2, ответы на этот вопрос в основном уже не верны. Новый оператор $ lookup, добавленный в конвейер агрегации, по сути идентичен левому внешнему соединению:
https://docs.mongodb.org/master/reference/operator/aggregation/lookup/#pipe._S_lookup
Из документов:
Конечно, Mongo не является реляционной базой данных, и разработчики стараются рекомендовать конкретные варианты использования для $ lookup, но, по крайней мере, начиная с 3.2, теперь возможно объединение с MongoDB.
источник
Эта страница на официальном сайте mongodb посвящена именно этому вопросу:
https://mongodb-documentation.readthedocs.io/en/latest/ecosystem/tutorial/model-data-for-ruby-on-rails.html
источник
Мы можем объединить / объединить все данные только в одной коллекции с помощью простой функции в несколько строк с помощью клиентской консоли mongodb, и теперь мы можем выполнить требуемый запрос. Ниже полный пример,
.- Авторы:
.- Категории:
.- Книги
.- Книжное кредитование
.- Магия:
.- Получить новые данные коллекции:
.- Отклик :)
Я надеюсь, что эти строки могут помочь вам.
источник
Вы должны сделать это так, как вы описали. MongoDB является нереляционной базой данных и не поддерживает объединения.
источник
Как уже отмечали другие, вы пытаетесь создать реляционную базу данных из не реляционной базы данных, которую вы действительно не хотите делать, но в любом случае, если у вас есть такой случай, вам нужно использовать это решение. Сначала мы делаем поиск foreach в коллекции A (или в вашем случае пользователей), а затем мы получаем каждый элемент как объект, затем мы используем свойство объекта (в вашем случае uid) для поиска во второй коллекции (в комментариях к вашему случаю), если мы может найти его, тогда у нас есть совпадение, и мы можем напечатать или сделать что-то с ним. Надеюсь, это поможет вам и удачи :)
источник
С правильной комбинацией $ lookup , $ project и $ match вы можете объединять несколько таблиц по нескольким параметрам. Это потому, что они могут быть связаны несколько раз.
Предположим, мы хотим сделать следующее ( ссылка )
Шаг 1: связать все таблицы
Вы можете найти столько таблиц, сколько захотите.
$ lookup - по одному для каждой таблицы в запросе
$ размотки - потому что данные корректно денормализованы, иначе они обернуты в массивы
Код Python ..
Шаг 2. Определите все условия
$ проект : определите здесь все условные операторы, а также все переменные, которые вы хотите выбрать.
Код Python ..
Шаг 3: Присоединяйся ко всем условностям
$ match - объединить все условия, используя OR или AND и т. д. Их может быть несколько.
$ project : отменить все условия
Код Python ..
Таким образом можно выполнить практически любую комбинацию таблиц, условий и объединений.
источник
Вот пример «объединения» * коллекций актеров и фильмов :
https://github.com/mongodb/cookbook/blob/master/content/patterns/pivot.txt
Это использует
.mapReduce()
метод* join - альтернатива объединению в документно-ориентированных базах данных
источник
Вы можете объединить две коллекции в Mongo, используя поиск, который предлагается в версии 3.2. В вашем случае запрос будет
или вы также можете присоединиться к пользователям, тогда будут небольшие изменения, как указано ниже.
Это будет работать так же, как левое и правое соединение в SQL.
источник
Это зависит от того, что вы пытаетесь сделать.
В настоящее время она настроена как нормализованная база данных, и это хорошо, и то, как вы это делаете, подходит.
Однако есть и другие способы сделать это.
У вас может быть коллекция постов, в которой есть встроенные комментарии для каждого поста со ссылками на пользователей, которых вы можете запросить итеративно. Вы можете хранить имя пользователя с комментариями, вы можете хранить их все в одном документе.
Суть в NoSQL заключается в том, что он предназначен для гибких схем и очень быстрого чтения и записи. В типичной ферме больших данных база данных является самым узким местом, у вас меньше механизмов баз данных, чем у приложений и серверов переднего плана ... они более дорогие, но более мощные, а также пространство на жестком диске сравнительно дешево. Нормализация исходит из концепции попыток сэкономить пространство, но она требует затрат на выполнение ваших баз данных для выполнения сложных объединений и проверки целостности отношений, выполнения каскадных операций. Все это избавляет разработчиков от головной боли, если они правильно спроектировали базу данных.
В NoSQL, если вы согласны с тем, что избыточность и пространство хранения не являются проблемами из-за их стоимости (как из-за процессорного времени, необходимого для обновления, так и из-за затрат на жесткий диск для хранения дополнительных данных), денормализация не является проблемой (для встроенных массивов, которые становятся Для сотен тысяч предметов это может быть проблемой производительности, но в большинстве случаев это не проблема). Кроме того, у вас будет несколько серверов приложений и серверов переднего плана для каждого кластера баз данных. Пусть они сделают тяжелую работу по объединению и позволят серверам баз данных придерживаться чтения и записи.
TL; DR: То, что вы делаете, хорошо, и есть другие способы сделать это. Посмотрите шаблоны моделей данных документации mongodb для некоторых замечательных примеров. http://docs.mongodb.org/manual/data-modeling/
источник
Существует спецификация, которую поддерживают многие драйверы, которая называется DBRef.
Взято из документации MongoDB: Модели данных> Справочник по моделям данных> Ссылки на базы данных
источник
$ lookup (агрегат)
Выполняет левое внешнее объединение с неотмеченной коллекцией в той же базе данных для фильтрации документов из «объединенной» коллекции для обработки. К каждому входному документу этап поиска $ добавляет новое поле массива, элементами которого являются совпадающие документы из «объединенной» коллекции. Этап поиска $ передает эти измененные документы на следующий этап. Этап $ lookup имеет следующие синтаксисы:
Равенство Матч
Чтобы выполнить сравнение на равенство между полем из входных документов и полем из документов «объединенной» коллекции, этап $ lookup имеет следующий синтаксис:
Операция будет соответствовать следующему псевдо-SQL-выражению:
Монго URL
источник
До 3.2.6 Mongodb не поддерживает запрос соединения, как и MySQL. ниже решение, которое работает для вас.
источник
Вы можете запускать SQL-запросы, включая соединение с MongoDB, с помощью mongo_fdw из Postgres.
источник
MongoDB не разрешает объединения, но вы можете использовать плагины для этого. Проверьте плагин Mongo-Join. Это лучшее, и я уже использовал его. Вы можете установить его, используя npm, вот так
npm install mongo-join
. Вы можете проверить полную документацию с примерами .(++) действительно полезный инструмент, когда нам нужно объединить (N) коллекции
(-) мы можем применять условия только на верхнем уровне запроса
пример
источник
Вы можете сделать это с помощью конвейера агрегации, но написать это самостоятельно - боль.
Вы можете использовать
mongo-join-query
для автоматического создания конвейера агрегации из вашего запроса.Вот как будет выглядеть ваш запрос:
Ваш результат будет иметь пользовательский объект в
uid
поле, и вы можете связать столько уровней, сколько захотите. Вы можете заполнить ссылку на пользователя, которая ссылается на команду, которая ссылается на что-то еще и т. Д.Отказ от ответственности : я написал,
mongo-join-query
чтобы решить эту проблему.источник
PlayORM может сделать это для вас, используя S-SQL (Scalable SQL), который просто добавляет разбиение, так что вы можете делать соединения внутри разделов.
источник
Нет, не похоже, что ты делаешь это неправильно. Присоединения MongoDB являются "клиентской стороной". Совсем как ты сказал:
Это не «реальное» соединение, но на самом деле оно намного более полезно, чем соединение SQL, потому что вам не нужно иметь дело с дублирующимися строками для «многих» двусторонних объединений, вместо того, чтобы декорировать первоначально выбранный набор.
На этой странице много чепухи и FUD. Оказывается, 5 лет спустя MongoDB все еще вещь.
источник
Я думаю, если вам нужны нормализованные таблицы данных - вам нужно попробовать другие решения для баз данных.
Но я основал это решение для MOngo в Git. Кстати, в коде вставок - у него есть название фильма, но идентификатор noi фильма .
проблема
У вас есть коллекция актеров с массивом фильмов, которые они сняли.
Вы хотите создать коллекцию фильмов с массивом актеров в каждом.
Некоторые образцы данных
Решение
Нам нужно пройтись по каждому фильму в документе Actor и создать каждый фильм отдельно.
Улов здесь находится в стадии снижения. Мы не можем создать массив из фазы сокращения, поэтому мы должны построить массив Actors внутри возвращаемого документа «value».
КодОбратите внимание, что actor_list на самом деле является объектом javascript, который содержит массив. Также обратите внимание, что карта испускает ту же структуру.
Запустите следующую команду, чтобы выполнить map / lower, вывести ее в коллекцию «pivot» и распечатать результат:
printjson (db.actors.mapReduce (map, lower, "pivot")); db.pivot.find () Foreach (printjson).
Вот пример выходных данных, обратите внимание, что в «Красотке» и «Сбежавшей невесте» есть и «Ричард Гир», и «Джулия Робертс».
источник
Мы можем объединить две коллекции, используя подзапрос mongoDB. Вот пример, комментарии-
Userss--
Подзапрос MongoDB для JOIN--
Получить результат из вновь созданной коллекции--
Результат--
Надеюсь, это поможет.
источник