Gestione dei tipi di elenco con Esqueleto


144

Ho tipi di dati definiti come:

data ComitteeView = CommitteeView { committeeId :: CommitteeId
                                  , committeeMembers :: [Person] 
                                  }

data CommitteesView = CommitteesView { committeeView :: [CommitteeView] }

Ora, così com'è, ho un modello persistente definito come:

Person
  name  Text

Committee
  name  Text

CommitteePerson
  personId    PersonId
  committeeId CommitteeId

Posso facilmente creare una query per popolare un Committee View, usando Esqueleto. Andrebbe qualcosa del genere:

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

Ora, considera il problema di popolare CommitteesView. In linea di principio, otteniamo dati sufficienti per popolare eseguendo la query secondaria nella query sopra. Va bene, abbastanza giusto. Ora come posso usare "raggruppa per elenco Haskell" come group byin SQL? Come posso piegare le righe in modo da poter finire con un elenco di elenchi di persone?

Ho l'impressione che esqueletonon possa gestire il caso in quanto tale (cioè, non ha un combinatore che lo farebbe). E il mio database sottostante ovviamente non supporta gli elenchi Haskell come una colonna. Ma, sicuramente, non posso essere l'unica persona ad affrontare questo problema. Che cos'è una strategia efficace? Piegare una n-list di liste in una n-list? O eseguendo n+1query? Ci sono altre opzioni?


2
Hai visto Data.List.groupBy?
cdk,

@cdk: Sì, è quello con cui sto andando. Diventa sorprendentemente peloso, però.
nomen,

Risposte:


2

Esqueleto NON intende ancora gestire un elenco di elenchi secondari (elenco multidimensionale)! Data.List.groupByquel "cdk" che ti è stato consigliato può raggruppare solo la lista stessa, ma non quello che stavi chiedendo.

Per il tuo caso, ti consiglio caldamente di utilizzare una query SQL classica. È possibile eseguire n + 1 query, ma farlo solo se è una funzione rara e non spesso utilizzabile, che ad esempio prepara i dati memorizzati nella cache (in base ai nomi delle variabili suppongo che potrebbe non essere utilizzato pesantemente e vale la pena provare). Per un uso intensivo dovresti considerare di utilizzare SQL classico senza alcun dubbio.

Se vai su https://github.com/prowdsponsor/esqueleto troverai che:

Non tutte le funzionalità SQL sono disponibili, ma la maggior parte di esse può essere facilmente aggiunta (in particolare le funzioni).

così puoi provare a chiedere una nuova funzionalità. In bocca al lupo!


Hai un link a una fonte su questo? Sarò felice di assegnare la ricompensa se qualcuno può verificare che questa sia la risposta corretta o è possibile fornire qualche tipo di documentazione.
Tech Savant,

@ NotoriousPet0 Se vai sul sito di haskell troverai un elenco completo di esempi e casi d'uso e nessuno di essi utilizza elenchi multidimensionali, anche "join interno". Se cerchi un "gruppo per" lì, scoprirai che può essere usato per racchiudere più colonne in una tupla o ordinare per funzione aggregata aggiuntiva. Si dice anche che gli sviluppatori provano a rendere Esqueleto tanto flessibile da supportare qualsiasi query, quindi puoi richiedere un'estensione aggiuntiva qui .
Kainax,
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.