次のように定義されたデータ型があります。
data ComitteeView = CommitteeView { committeeId :: CommitteeId
, committeeMembers :: [Person]
}
data CommitteesView = CommitteesView { committeeView :: [CommitteeView] }
さて、現状では、次のように定義された永続モデルがあります。
Person
name Text
Committee
name Text
CommitteePerson
personId PersonId
committeeId CommitteeId
Esqueletoを使用すると、CommitteetViewにデータを入力するクエリを簡単に作成できます。それは次のようなものになります:
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
次に、CommitteesView
への入力の問題を考えます。原則として、上記のクエリでサブクエリを実行することで、入力するのに十分なデータを取得します。わかりました。では、SQLでgroup by
のような「group by Haskell-list」をどのように使用できますか?行を折り畳んで、人のリストのリストを作成するにはどうすればよいですか?
esqueleto
はそのようなケースを処理できない(つまり、それを行うコンビネーターがない)という印象を受けます。そして、私の基になるデータベースは明らかに列としてのHaskellリストをサポートしていません。しかし、確かに、この問題に直面するのは私だけではありません。効果的な戦略とは何ですか?リストのnリストをnリストに折りたたみますか?またはn+1
クエリを実行していますか?他のオプションはありますか?
Esqueletoは[〜#〜]ではありません[〜#〜]は、サブリストのリスト(多次元リスト)をそのまま使用できることを意味します! Data.List.groupBy
「cdk」があなたに忠告したのは、リスト自体だけで、あなたが求めていたものはグループ化できないということです。
あなたのケースでは、私はしつこく古典的なSQLクエリを使用することをお勧めします。 n + 1クエリを実行することはできますが、それが実行されるのはまれで、頻繁に使用できる機能ではない場合のみです。たとえば、キャッシュされたデータを準備します(変数名に基づいて、頻繁に使用されることはなく、試してみる価値があると思います)。頻繁に使用する場合は、疑いなくクラシックSQLの使用を検討してください。
https://github.com/prowdsponsor/esqueleto にアクセスすると、次のことがわかります。
すべてのSQL機能が使用できるわけではありませんが、それらのほとんど(特に関数)は簡単に追加できます。
新しい機能をリクエストしてみてください。幸運を!