使用Esqueleto处理List类型

时间:2014-05-20 04:41:10

标签: sql list haskell esqueleto

我将数据类型定义为:

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

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

现在,就目前而言,我将Persistent模型定义为:

Person
  name  Text

Committee
  name  Text

CommitteePerson
  personId    PersonId
  committeeId CommitteeId

我可以使用Esqueleto轻松创建一个填充委员会视图的查询。它会是这样的:

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的问题。原则上,我们通过在上面的查询中运行子查询来获取足够的数据来填充。好的,公平的。现在我如何使用&#34; group by Haskell-list&#34;像SQL中的group by?如何折叠行以便最终得到人员列表?

我得到的印象是esqueleto无法处理这种情况(即,它没有一个能够做到这一点的组合器)。而我的底层数据库显然不支持Haskell列表作为列。但是,当然,我不能成为唯一一个面对这个问题的人。什么是有效的策略?将n列表列表折叠到n列表中?或者运行n+1个查询?还有其他选择吗?

1 个答案:

答案 0 :(得分:2)

Esqueleto NOT 用于处理开箱即用的子列表(多维列表)列表! Data.List.groupBy那是&#39; cdk&#39;建议你可以只分组本身,但不是你所要求的。

对于您的情况,我会坚持建议您使用经典的SQL查询。您可以运行n + 1个查询,但只有在它很少且通常不可用的函数时才这样做,例如准备缓存数据(基于您的变量名称,我认为它可能不会被大量使用,值得一试)。对于大量使用,您应该毫无疑问地考虑使用经典SQL。

如果您要转到https://github.com/prowdsponsor/esqueleto,您会发现:

  

并非所有SQL功能都可用,但大多数功能都很简单   添加(特别是功能)。

因此您可以尝试申请新功能。祝你好运!