我将数据类型定义为:
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
个查询?还有其他选择吗?
答案 0 :(得分:2)
Esqueleto NOT 用于处理开箱即用的子列表(多维列表)列表! Data.List.groupBy
那是&#39; cdk&#39;建议你可以只分组本身,但不是你所要求的。
对于您的情况,我会坚持建议您使用经典的SQL查询。您可以运行n + 1个查询,但只有在它很少且通常不可用的函数时才这样做,例如准备缓存数据(基于您的变量名称,我认为它可能不会被大量使用,值得一试)。对于大量使用,您应该毫无疑问地考虑使用经典SQL。
如果您要转到https://github.com/prowdsponsor/esqueleto,您会发现:
并非所有SQL功能都可用,但大多数功能都很简单 添加(特别是功能)。
因此您可以尝试申请新功能。祝你好运!