Обробка типів списку за допомогою 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

Я можу досить легко створити запит, щоб заповнити CommitteeView, використовуючи 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. В принципі, ми отримуємо достатньо даних для заповнення, запустивши підзапрос у вищезазначеному запиті. Гаразд, досить справедливо. Тепер як я можу використовувати "group by Haskell-list", як group byу SQL? Як я можу складати рядки, щоб я міг описувати список списків людей?

У мене esqueletoскладається враження, що він не може вирішити справу як таку (тобто у неї немає комбінатора, який би це зробив). І моя база даних очевидно не підтримує списки Haskell як стовпчик. Але, безумовно, я не можу бути єдиною людиною, яка зіткнулася з цим питанням. Що таке ефективна стратегія? Складання n-списків списків у n-список? Або запущені n+1запити? Чи є інші варіанти?


2
Ви подивилися Data.List.groupBy?
cdk

@cdk: Так, саме з цим я йшов. Це стає напрочуд волохатим, хоча.
номен

Відповіді:


2

Esqueleto НЕ призначений для обробки списків списків (багатовимірний список) поза коробкою! Data.List.groupByщо рекомендується вам "cdk", можна групувати лише список себе, але не те, про що ви просили.

У вашому випадку я наполегливо рекомендую вам використовувати класичні запити SQL. Ви можете запускати n + 1 запити, але робіть це лише в тому випадку, якщо це рідкісна і не часто зручна функція, наприклад, готується кешовані дані (на основі імен ваших змінних, я вважаю, що вони можуть бути не важкими, і варто спробувати). Для інтенсивного використання вам слід розглянути можливість використання класичного SQL без сумнівів.

Якщо ви перейдете на сторінку https://github.com/prowdsponsor/esqueleto, ви побачите, що:

Не всі функції SQL доступні, але більшість з них можна легко додати (особливо функції).

тож ви можете спробувати попросити нову функцію. Удачі!


Чи є у вас посилання на джерело про це? Я буду радий нагородити нагороду, якщо хтось зможе підтвердити, що це правильна відповідь або ви можете надати якусь документацію.
Тех Савант

@ NotoriousPet0 Якщо ви перейдете на веб-сайт haskell, ви знайдете повний список прикладів і використовуйте випадки, і жоден з них не використовує багатовимірні списки, навіть "внутрішнє з'єднання". Якщо ви шукаєте там "групу за", то виявите, що вона може бути використана для укладання декількох стовпців в кортеж або сортування за додатковою функцією сукупності. Там також сказано, що розробники намагаються зробити Esqueleto максимально гнучким для підтримки будь-якого запиту, тому ви можете попросити додаткове розширення тут .
Кайнакс
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.