Wie führe ich das SQL Join-Äquivalent in MongoDB durch?
Angenommen, Sie haben zwei Sammlungen (Benutzer und Kommentare) und ich möchte alle Kommentare mit pid = 444 zusammen mit den Benutzerinformationen für jede Sammlung abrufen.
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" }
Gibt es eine Möglichkeit, alle Kommentare mit einem bestimmten Feld (z. B. ... find ({pid: 444})) und die mit jedem Kommentar verknüpften Benutzerinformationen auf einmal abzurufen?
Im Moment erhalte ich zuerst die Kommentare, die meinen Kriterien entsprechen, dann finde ich alle UIDs in dieser Ergebnismenge heraus, rufe die Benutzerobjekte ab und füge sie mit den Ergebnissen des Kommentars zusammen. Scheint, als würde ich es falsch machen.
Antworten:
Ab Mongo 3.2 sind die Antworten auf diese Frage meist nicht mehr richtig. Der neue $ lookup-Operator, der der Aggregationspipeline hinzugefügt wurde, ist im Wesentlichen identisch mit einem linken äußeren Join:
https://docs.mongodb.org/master/reference/operator/aggregation/lookup/#pipe._S_lookup
Aus den Dokumenten:
Natürlich ist Mongo keine relationale Datenbank, und die Entwickler empfehlen sorgfältig, bestimmte Anwendungsfälle für $ lookup zu empfehlen, aber ab Version 3.2 ist das Beitreten jetzt mit MongoDB möglich.
quelle
Diese Seite auf der offiziellen Mongodb-Website befasst sich genau mit dieser Frage:
https://mongodb-documentation.readthedocs.io/en/latest/ecosystem/tutorial/model-data-for-ruby-on-rails.html
quelle
Mit der Mongodb-Client-Konsole können wir alle Daten in nur einer Sammlung mit einer einfachen Funktion in wenigen Zeilen zusammenführen / verbinden. Jetzt können wir die gewünschte Abfrage ausführen. Unten ein vollständiges Beispiel:
.- Autoren:
.- Kategorien:
.- Bücher
.- Buchverleih
.- Die Magie:
.- Holen Sie sich die neuen Sammlungsdaten:
.- Antwort :)
Ich hoffe, diese Zeilen können Ihnen helfen.
quelle
Sie müssen es so machen, wie Sie es beschrieben haben. MongoDB ist eine nicht relationale Datenbank und unterstützt keine Joins.
quelle
Wie andere bereits betont haben, versuchen Sie, eine relationale Datenbank aus keiner relationalen Datenbank zu erstellen, was Sie wirklich nicht tun möchten, aber wenn Sie den Fall haben, dass Sie dies hier tun müssen, ist dies eine Lösung, die Sie verwenden können. Wir führen zuerst einen Foreach-Fund für Sammlung A (oder in Ihrem Fall für Benutzer) durch und erhalten dann jedes Element als Objekt. Anschließend verwenden wir die Objekteigenschaft (in Ihrem Fall uid), um in unserer zweiten Sammlung (in Ihren Fallkommentaren) nachzuschlagen, wenn wir dies tun kann es finden, dann haben wir eine Übereinstimmung und wir können drucken oder etwas damit machen. Hoffe das hilft dir und viel Glück :)
quelle
Mit der richtigen Kombination aus $ lookup , $ project und $ match können Sie mehrere Tabellen mit mehreren Parametern verknüpfen. Dies liegt daran, dass sie mehrfach verkettet werden können.
Angenommen, wir möchten Folgendes tun ( Referenz )
Schritt 1: Verknüpfen Sie alle Tabellen
Sie können so viele Tabellen nachschlagen, wie Sie möchten.
$ lookup - eine für jede Tabelle in der Abfrage
$ unwind - weil Daten korrekt denormalisiert sind, sonst in Arrays eingeschlossen
Python-Code ..
Schritt 2: Definieren Sie alle Bedingungen
$ project : Definieren Sie hier alle bedingten Anweisungen sowie alle Variablen, die Sie auswählen möchten.
Python Code ..
Schritt 3: Verbinden Sie alle Bedingungen
$ match - Verbinde alle Bedingungen mit ODER oder UND usw. Es kann ein Vielfaches davon geben.
$ project : Undefiniere alle Bedingungen
Python Code ..
Auf diese Weise kann so ziemlich jede Kombination von Tabellen, Bedingungen und Verknüpfungen durchgeführt werden.
quelle
Hier ist ein Beispiel für eine "Join" * -Sammlung von Schauspielern und Filmen :
https://github.com/mongodb/cookbook/blob/master/content/patterns/pivot.txt
Es bedient sich der
.mapReduce()
Methode* join - eine Alternative zum Beitritt zu dokumentorientierten Datenbanken
quelle
Sie können zwei Sammlungen in Mongo verbinden, indem Sie die Suche verwenden, die in der Version 3.2 angeboten wird. In Ihrem Fall wäre die Abfrage
oder Sie können auch in Bezug auf Benutzer beitreten, dann wird es eine kleine Änderung geben, wie unten angegeben.
Es funktioniert genauso wie die Verknüpfung von links und rechts in SQL.
quelle
Es hängt davon ab, was Sie versuchen zu tun.
Sie haben es derzeit als normalisierte Datenbank eingerichtet, was in Ordnung ist, und die Art und Weise, wie Sie es tun, ist angemessen.
Es gibt jedoch auch andere Möglichkeiten.
Sie könnten eine Postsammlung haben, in die Kommentare für jeden Post mit Verweisen auf die Benutzer eingebettet sind, die Sie iterativ abfragen können, um sie abzurufen. Sie können den Namen des Benutzers mit den Kommentaren speichern, Sie können sie alle in einem Dokument speichern.
Die Sache mit NoSQL ist, dass es für flexible Schemata und sehr schnelles Lesen und Schreiben ausgelegt ist. In einer typischen Big Data-Farm ist die Datenbank der größte Engpass. Sie haben weniger Datenbank-Engines als Anwendungs- und Front-End-Server. Sie sind teurer, aber leistungsfähiger. Auch der Festplattenspeicher ist vergleichsweise sehr billig. Die Normalisierung beruht auf dem Konzept, Speicherplatz zu sparen, ist jedoch mit Kosten verbunden, wenn Ihre Datenbanken komplizierte Verknüpfungen ausführen und die Integrität von Beziehungen überprüfen sowie Kaskadenvorgänge ausführen. All dies erspart den Entwicklern einige Kopfschmerzen, wenn sie die Datenbank richtig entworfen haben.
Wenn Sie mit NoSQL akzeptieren, dass Redundanz und Speicherplatz aufgrund ihrer Kosten keine Probleme darstellen (sowohl hinsichtlich der für Aktualisierungen erforderlichen Prozessorzeit als auch der Festplattenkosten für die Speicherung zusätzlicher Daten), ist die Denormalisierung kein Problem (für eingebettete Arrays, die zu Problemen werden) Hunderttausende von Elementen kann ein Leistungsproblem sein, aber meistens ist das kein Problem. Zusätzlich haben Sie mehrere Anwendungs- und Front-End-Server für jeden Datenbankcluster. Lassen Sie sie die Joins schwer anheben und die Datenbankserver beim Lesen und Schreiben bleiben.
TL; DR: Was Sie tun, ist in Ordnung, und es gibt andere Möglichkeiten, dies zu tun. In den Datenmodellmustern der Mongodb-Dokumentation finden Sie einige gute Beispiele. http://docs.mongodb.org/manual/data-modeling/
quelle
Es gibt eine Spezifikation, die viele Treiber unterstützen und die DBRef heißt.
Entnommen aus der MongoDB-Dokumentation: Datenmodelle> Datenmodellreferenz> Datenbankreferenzen
quelle
$ lookup (Aggregation)
Führt eine linke äußere Verknüpfung zu einer nicht gesicherten Sammlung in derselben Datenbank durch, um Dokumente aus der "verbundenen" Sammlung zur Verarbeitung zu filtern. Zu jedem Eingabedokument fügt die $ lookup-Phase ein neues Array-Feld hinzu, dessen Elemente die übereinstimmenden Dokumente aus der "verbundenen" Sammlung sind. Die $ lookup-Phase übergibt diese umgeformten Dokumente an die nächste Phase. Die $ lookup-Phase hat die folgenden Syntaxen:
Gleichstellungsübereinstimmung
Um eine Gleichheitsübereinstimmung zwischen einem Feld aus den Eingabedokumenten und einem Feld aus den Dokumenten der "verbundenen" Sammlung durchzuführen, hat die $ lookup-Phase die folgende Syntax:
Die Operation würde der folgenden Pseudo-SQL-Anweisung entsprechen:
Mongo URL
quelle
Vor 3.2.6 unterstützt Mongodb keine Join-Abfrage wie MySQL. unten Lösung, die für Sie funktioniert.
quelle
Sie können SQL-Abfragen einschließlich Join in MongoDB mit mongo_fdw von Postgres ausführen .
quelle
MongoDB erlaubt keine Joins, aber Sie können Plugins verwenden, um dies zu handhaben. Überprüfen Sie das Mongo-Join-Plugin. Es ist das Beste und ich habe es bereits benutzt. Sie können es mit npm direkt so installieren
npm install mongo-join
. Sie können die vollständige Dokumentation mit Beispielen überprüfen .(++) wirklich hilfreiches Tool, wenn wir (N) Sammlungen beitreten müssen
(-) Wir können Bedingungen nur auf der obersten Ebene der Abfrage anwenden
Beispiel
quelle
Sie können dies mithilfe der Aggregationspipeline tun, aber es ist schwierig, es selbst zu schreiben.
Sie können
mongo-join-query
die Aggregationspipeline automatisch aus Ihrer Abfrage erstellen.So würde Ihre Anfrage aussehen:
Ihr Ergebnis würde das Benutzerobjekt im
uid
Feld haben und Sie können so viele Ebenen verknüpfen, wie Sie möchten. Sie können den Verweis auf den Benutzer ausfüllen, der auf ein Team verweist, auf etwas anderes verweist usw.Haftungsausschluss : Ich habe geschrieben
mongo-join-query
, um genau dieses Problem anzugehen.quelle
playORM kann dies für Sie mit S-SQL (Scalable SQL) tun, das lediglich die Partitionierung hinzufügt, sodass Sie Verknüpfungen innerhalb von Partitionen durchführen können.
quelle
Nein, es scheint nicht so, als ob du es falsch machst. MongoDB-Joins sind "clientseitig". So ziemlich wie du gesagt hast:
Es ist kein "echter" Join, aber es ist tatsächlich viel nützlicher als ein SQL-Join, da Sie sich nicht mit doppelten Zeilen für "viele" einseitige Joins befassen müssen, sondern stattdessen den ursprünglich ausgewählten Satz dekorieren müssen.
Auf dieser Seite gibt es viel Unsinn und FUD. Es stellt sich heraus, dass MongoDB 5 Jahre später immer noch eine Sache ist.
quelle
Ich denke, wenn Sie normalisierte Datentabellen benötigen, müssen Sie einige andere Datenbanklösungen ausprobieren.
Aber ich habe diese Lösung für MOngo auf Git gefunden. Übrigens, in Code einfügen - es hat den Namen des Films, aber die ID des Noi-Films .
Problem
Sie haben eine Sammlung von Schauspielern mit einer Reihe von Filmen, die sie gemacht haben.
Sie möchten eine Sammlung von Filmen mit jeweils einer Reihe von Akteuren erstellen.
Einige Beispieldaten
Lösung
Wir müssen jeden Film im Actor-Dokument durchlaufen und jeden Film einzeln ausgeben.
Der Haken liegt hier in der Reduktionsphase. Wir können kein Array aus der Reduktionsphase ausgeben, daher müssen wir ein Actors-Array innerhalb des zurückgegebenen "Wert" -Dokuments erstellen.
Der CodeBeachten Sie, dass actor_list tatsächlich ein Javascript-Objekt ist, das ein Array enthält. Beachten Sie auch, dass die Karte dieselbe Struktur ausgibt.
Führen Sie die folgenden Schritte aus, um die Map / Reduce auszuführen, geben Sie sie in die "Pivot" -Sammlung aus und drucken Sie das Ergebnis:
printjson (db.actors.mapReduce (map, redu, "pivot")); db.pivot.find (). forEach (printjson);
Hier ist die Beispielausgabe. Beachten Sie, dass "Pretty Woman" und "Runaway Bride" sowohl "Richard Gere" als auch "Julia Roberts" haben.
quelle
Wir können zwei Sammlungen mithilfe der mongoDB-Unterabfrage zusammenführen. Hier ist ein Beispiel, Commentss--
Benutzer--
MongoDB-Unterabfrage für JOIN--
Ergebnis aus neu generierter Sammlung abrufen--
Ergebnis--
Hoffe, das wird helfen.
quelle