Ich habe Datentypen definiert als:
data ComitteeView = CommitteeView { committeeId :: CommitteeId
, committeeMembers :: [Person]
}
data CommitteesView = CommitteesView { committeeView :: [CommitteeView] }
So wie es aussieht, habe ich ein beständiges Modell definiert als:
Person
name Text
Committee
name Text
CommitteePerson
personId PersonId
committeeId CommitteeId
Ich kann mit Esqueleto ziemlich einfach eine Abfrage erstellen, um eine CommitteeView zu füllen. Es würde ungefähr so aussehen:
getCommitteeView cid =
CommitteeView <$> runDB $
select $
from (person `InnerJoin` pxc `InnerJoin` committee) -> do
on (committee ^. CommitteeId ==. pxc ^. CommitteePersonCommitteeId)
on (person ^. PersonId ==. pxc ^. CommitteePersonPersonId)
where_ (committee ^. CommitteePersonCommitteeId ==. val cid)
return person
Betrachten Sie nun das Problem der Besiedlung CommitteesView
. Im Prinzip erhalten wir genügend Daten zum Auffüllen, indem wir die Unterabfrage in der obigen Abfrage ausführen. Okay, fair genug. Wie kann ich nun "Gruppe nach Haskell-Liste" wie group by
in SQL verwenden? Wie kann ich Zeilen falten, um eine Liste mit Personenlisten zu erhalten?
Ich habe den Eindruck, dass esqueleto
der Fall als solcher nicht behandelt werden kann (dh es gibt keinen Kombinator, der dies tun würde). Und meine zugrunde liegende Datenbank unterstützt offensichtlich keine Haskell-Listen als Spalte. Aber ich kann sicherlich nicht die einzige Person sein, die sich diesem Problem stellt. Was ist eine effektive Strategie? Eine n-Liste von Listen in eine n-Liste falten? Oder n+1
Abfragen ausführen? Gibt es noch andere Möglichkeiten?
Data.List.groupBy
?Antworten:
Esqueleto ist noch NICHT dazu gedacht, die Liste der Unterlisten (mehrdimensionale Liste) sofort zu verarbeiten!
Data.List.groupBy
Das 'cdk', das Ihnen empfohlen wurde, kann nur die Liste selbst gruppieren, aber nicht das, wonach Sie gefragt haben.Für Ihren Fall würde ich Ihnen eindringlich raten, klassische SQL-Abfragen zu verwenden. Sie können n + 1 Abfragen ausführen, dies jedoch nur, wenn es sich um eine seltene und nicht häufig verwendbare Funktion handelt, die beispielsweise zwischengespeicherte Daten vorbereitet (basierend auf Ihren Variablennamen nehme ich an, dass sie möglicherweise nicht häufig verwendet werden und einen Versuch wert sind). Bei starker Beanspruchung sollten Sie ohne Zweifel die Verwendung von klassischem SQL in Betracht ziehen.
Wenn Sie zu https://github.com/prowdsponsor/esqueleto gehen, finden Sie Folgendes:
Sie können also versuchen, nach einer neuen Funktion zu fragen. Viel Glück!
quelle