144

次のように定義されたデータ型があります。

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

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

さて、現状では、次のように定義された永続モデルがあります。

Person
  name  Text

Committee
  name  Text

CommitteePerson
  personId    PersonId
  committeeId CommitteeId

Esqueleto を使用して、CommitteeView に入力するクエリを簡単に作成できます。次のようになります。

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。原則として、上記のクエリでサブクエリを実行することにより、入力するのに十分なデータを取得します。わかりました、十分に公平です。group bySQLのように「Haskell-listによるグループ」を使用するにはどうすればよいですか? 人のリストのリストになるように行を折りたたむにはどうすればよいですか?

esqueletoそのようなケースを処理できない (つまり、それを行うコンビネータがない)という印象を受けます。そして、私の基盤となるデータベースは明らかに Haskell リストを列としてサポートしていません。しかし、確かに、この問題に直面しているのは私だけではありません。効果的な戦略とは?リストのnリストをnリストに折りたたむ? またはn+1クエリを実行していますか?他のオプションはありますか?

4

1 に答える 1

2

Esqueleto は、まだそのままではサブリストのリスト (多次元リスト) を処理するためのものではありません! Data.List.groupByその「cdk」は、リスト自体のみをグループ化できますが、あなたが求めていたものはグループ化できません。

あなたの場合、古典的な SQL クエリを使用することを強くお勧めします。n+1 クエリを実行できますが、キャッシュされたデータを準備するなど、まれで頻繁に使用できない関数である場合にのみ実行してください(変数名に基づいて、頻繁に使用されることはなく、試してみる価値があると思います)。頻繁に使用する場合は、間違いなくクラシック SQL の使用を検討する必要があります。

https://github.com/prowdsponsor/esqueletoにアクセスすると、次のことがわかります。

すべての SQL 機能が利用できるわけではありませんが、それらのほとんどは簡単に追加できます (特に関数)。

新しい機能を求めることができます。幸運を!

于 2015-07-12T07:35:28.623 に答える