使用Esqueleto处理列表types
我有数据types定义为:
data ComitteeView = CommitteeView { committeeId :: CommitteeId , committeeMembers :: [Person] } data CommitteesView = CommitteesView { committeeView :: [CommitteeView] }
现在,现在,我有一个永久模型定义为:
Person name Text Committee name Text CommitteePerson personId PersonId committeeId CommitteeId
我可以很容易地创build一个查询来填充一个委托,使用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
的问题。 原则上,我们通过在上面的查询中运行子查询来获取足够的数据。 好吧,够公平的 现在我怎么可以像在SQL一样使用“由Haskell-list group by
”? 我怎样才能折行,以便我可以列出人名单?
我觉得esqueleto
不能处理这种情况(也就是说,没有一个combinator可以)。 而我的底层数据库显然不支持Haskell列表作为列。 但是,当然,我不能成为唯一面对这个问题的人。 什么是有效的策略? 将列表的n列表折叠到n列表中? 或者运行n+1
查询? 还有其他的select吗?
Esqueleto并不是要处理开箱子列表(多维列表)! Data.List.groupBy
通过“cdk”build议你可以只列出自己的列表,而不是你所要求的。
对于你的情况,我会坚持build议你使用传统的SQL查询。 你可以运行n + 1个查询,但是只有在罕见和不常用的function的时候才可以运行,例如准备好caching的数据(根据你的variables名称,我认为它可能不会被大量使用,值得一试)。 对于繁重的使用,你应该考虑使用传统的SQL毫无疑问。
如果你会去https://github.com/prowdsponsor/esqueleto你会发现:;
并非所有的SQLfunction都可用,但其中大部分都可以轻松添加(特别是function)。
所以你可以尝试要求一个新的function。 祝你好运!