다음과 같이 정의 된 데이터 유형이 있습니다.
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를 사용하여 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 에서처럼 “group by Haskell-list”를 어떻게 사용할 수 있습니까? 사람들의 목록으로 끝나도록 행을 어떻게 접을 수 있습니까?
esqueleto
사례를 처리 할 수없는 인상을받습니다 (즉,이를 수행 할 결합기가 없습니다). 그리고 내 기본 데이터베이스는 분명히 Haskell 목록을 열로 지원하지 않습니다. 그러나 분명히이 문제에 직면 할 수있는 유일한 사람은 아닙니다. 효과적인 전략은 무엇입니까? n- 목록을 n- 목록으로 접기? 아니면 n+1
쿼리를 실행 합니까? 다른 옵션이 있습니까?
답변
Esqueleto는 아직 하위 목록 (다차원 목록) 목록을 처리 하지 않습니다 . Data.List.groupBy
그 ‘cdk’는 그룹 자체 만 나열 할 수 있지만 요청한 것은 아닙니다.
귀하의 경우 고전적인 SQL 쿼리를 사용하는 것이 좋습니다. n + 1 쿼리를 실행할 수 있지만 드물고 자주 사용할 수없는 기능 인 경우에만 캐시 된 데이터를 준비하는 것과 같이 수행하십시오 (변수 이름을 기반으로 많이 사용되지 않을 수도 있고 시도해 볼 가치가 있다고 생각합니다). 사용량이 많은 경우 의심의 여지없이 클래식 SQL 사용을 고려해야합니다.
https://github.com/prowdsponsor/esqueleto 로 이동하면 다음을 찾을 수 있습니다.
모든 SQL 기능을 사용할 수있는 것은 아니지만 대부분의 기능을 쉽게 추가 할 수 있습니다 (특히 기능).
새로운 기능을 요청할 수 있습니다. 행운을 빕니다!