Mongoid hat keine has_many: through oder eine gleichwertige Funktion. Es wäre mit MongoDB nicht so nützlich, da es keine Join-Abfragen unterstützt. Selbst wenn Sie eine verwandte Sammlung über eine andere referenzieren könnten, wären dennoch mehrere Abfragen erforderlich.
https://github.com/mongoid/mongoid/issues/544
Wenn Sie in einem RDBMS eine Viele-Viele-Beziehung haben, modellieren Sie diese normalerweise in MongoDB anders, indem Sie ein Feld verwenden, das auf beiden Seiten ein Array von 'Fremdschlüsseln' enthält. Beispielsweise:
class Physician
include Mongoid::Document
has_and_belongs_to_many :patients
end
class Patient
include Mongoid::Document
has_and_belongs_to_many :physicians
end
Mit anderen Worten, Sie würden die Join-Tabelle entfernen und sie hätte einen ähnlichen Effekt wie has_many: durch in Bezug auf den Zugriff auf die 'andere Seite'. In Ihrem Fall ist dies jedoch wahrscheinlich nicht angemessen, da Ihre Join-Tabelle eine Terminklasse ist, die einige zusätzliche Informationen enthält, nicht nur die Zuordnung.
Wie Sie dies modellieren, hängt in gewissem Maße von den Abfragen ab, die Sie ausführen müssen. Es scheint jedoch, als müssten Sie das Terminmodell hinzufügen und Assoziationen zu Patient und Arzt wie folgt definieren:
class Physician
include Mongoid::Document
has_many :appointments
end
class Appointment
include Mongoid::Document
belongs_to :physician
belongs_to :patient
end
class Patient
include Mongoid::Document
has_many :appointments
end
Bei Beziehungen in MongoDB müssen Sie immer zwischen eingebetteten oder zugeordneten Dokumenten wählen. In Ihrem Modell würde ich vermuten, dass MeetingNotes ein guter Kandidat für eine eingebettete Beziehung sind.
class Appointment
include Mongoid::Document
embeds_many :meeting_notes
end
class MeetingNote
include Mongoid::Document
embedded_in :appointment
end
Dies bedeutet, dass Sie die Notizen zusammen mit einem Termin abrufen können, während Sie mehrere Abfragen benötigen würden, wenn dies eine Zuordnung wäre. Sie müssen nur die Größenbeschränkung von 16 MB für ein einzelnes Dokument berücksichtigen, die möglicherweise ins Spiel kommt, wenn Sie über eine sehr große Anzahl von Besprechungsnotizen verfügen.
Um dies zu erweitern, sind hier die Modelle, die um Methoden erweitert wurden, die sich sehr ähnlich wie has_many verhalten: von ActiveRecord durch Zurückgeben eines Abfrage-Proxys anstelle eines Arrays von Datensätzen:
quelle
.pluck()
sinstead of VIEL.map
schneller. Können Sie Ihre Antwort für zukünftige Leser aktualisieren?undefined method 'pluck' for #<Array:...>
Steven Soroka Lösung ist wirklich toll! Ich habe nicht den Ruf, eine Antwort zu kommentieren (deshalb füge ich eine neue Antwort hinzu: P), aber ich denke, die Verwendung einer Karte für eine Beziehung ist teuer (insbesondere, wenn Ihre has_many-Beziehung Hunderte | Tausende von Datensätzen enthält), weil sie erhalten wird Die Daten aus der Datenbank erstellen jeden Datensatz, generieren das ursprüngliche Array und iterieren dann über das ursprüngliche Array, um ein neues mit den Werten aus dem angegebenen Block zu erstellen.
Das Zupfen ist schneller und vielleicht die schnellste Option.
Hier einige Statistiken mit Benchmark.measure:
Ich benutze nur 250 Termine. Vergessen Sie nicht, im Termindokument Indizes zu: patient_id und: doctor_id hinzuzufügen!
Ich hoffe es hilft, Danke fürs Lesen!
quelle
undefined method 'pluck' for #<Array:...>
Ich möchte diese Frage aus der Perspektive der selbstreferenzierenden Assoziation beantworten, nicht nur aus der Perspektive has_many: through.
Angenommen, wir haben ein CRM mit Kontakten. Kontakte haben Beziehungen zu anderen Kontakten, aber anstatt eine Beziehung zwischen zwei verschiedenen Modellen herzustellen, erstellen wir eine Beziehung zwischen zwei Instanzen desselben Modells. Ein Kontakt kann viele Freunde haben und mit vielen anderen Kontakten befreundet sein, daher müssen wir eine Viele-zu-Viele-Beziehung aufbauen.
Wenn wir ein RDBMS und ActiveRecord verwenden, würden wir has_many: through verwenden. Daher müssten wir ein Join-Modell wie Friendship erstellen. Dieses Modell verfügt über zwei Felder: eine Kontakt-ID, die den aktuellen Kontakt darstellt, der einen Freund hinzufügt, und eine Freund-ID, die den Benutzer darstellt, der befreundet ist.
Aber wir verwenden MongoDB und Mongoid. Wie oben erwähnt, verfügt Mongoid nicht über has_many: through oder eine gleichwertige Funktion. Es wäre mit MongoDB nicht so nützlich, da es keine Join-Abfragen unterstützt. Um eine Viele-Viele-Beziehung in einer Nicht-RDBMS-Datenbank wie MongoDB zu modellieren, verwenden Sie daher ein Feld, das auf beiden Seiten ein Array von 'Fremdschlüsseln' enthält.
Wie in der Dokumentation angegeben:
Für eine selbstreferenzierende Zuordnung in MongoDB haben Sie jetzt einige Optionen.
Was ist der Unterschied zwischen verwandten Kontakten und Kontakten, die viele haben und zu vielen Praktiken gehören? Großer Unterschied! Eine ist eine Beziehung zwischen zwei Entitäten. Andere ist eine Selbstreferenz.
quelle