使用Esqueleto处理列表类型


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 by在SQL中使用“按Haskell-list分组” ?如何折叠行,以便最终得到人员名单?

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


2
你看了Data.List.groupBy吗?
cdk 2014年

@cdk:是的,这就是我一直在做的。但是,它变得出奇的毛茸茸。
nomen 2014年

Answers:


2

Esqueleto 还不打算立即处理子列表(多维列表)!Data.List.groupBy建议您将“ cdk”仅分组列出自己,而不是您要的分组。

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

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

并非所有SQL功能都可用,但是可以轻松添加其中的大多数功能(尤其是函数)。

因此您可以尝试请求一项新功能。祝好运!


您是否有此链接的来源?如果有人可以验证这是正确的答案,或者您可以提供某种文档,我将很乐意奖励。
Tech Savant 2015年

@ NotoriousPet0如果您访问haskell网站,您将找到示例和用例的完整列表,并且没有一个使用多维列表,甚至没有“内部联接”。如果在其中搜索“分组依据”,您会发现它可用于将多列包含在元组中或按其他聚合函数进行排序。也有人说开发人员试图使Esqueleto尽可能灵活以支持任何查询,因此您可以在此处请求其他扩展。
Kainax
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.