การจัดการประเภทรายการด้วย 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ไม่สามารถจัดการกับกรณีดังกล่าวได้ (เช่นไม่มี combinator ที่จะทำ) และฐานข้อมูลพื้นฐานของฉันไม่สนับสนุนรายการ Haskell เป็นคอลัมน์ แต่แน่นอนฉันไม่สามารถเป็นคนเดียวที่จะเผชิญกับปัญหานี้ กลยุทธ์ที่มีประสิทธิภาพคืออะไร? การพับ n-list ของรายการลงใน n-list หรือไม่ หรือเรียกใช้n+1แบบสอบถาม มีตัวเลือกอื่น ๆ อีกไหม?


2
มีคุณดูData.List.groupBy?
cdk

@cdk: ใช่นั่นคือสิ่งที่ฉันได้ไปด้วย มันมีขนดกอย่างน่าประหลาดใจ
nomen

คำตอบ:


2

Esqueleto ไม่ได้หมายถึงการจัดการรายการย่อย (รายการหลายมิติ) ออกจากกล่องเลย! Data.List.groupByที่ 'cdk' แนะนำให้คุณสามารถจัดกลุ่มรายการตัวเองเท่านั้น แต่ไม่ใช่สิ่งที่คุณขอ

สำหรับกรณีของคุณฉันขอแนะนำให้คุณใช้แบบสอบถาม SQL แบบคลาสสิก คุณสามารถเรียกใช้การสอบถาม n + 1 แต่ทำได้เฉพาะในกรณีที่เป็นของหายากและไม่สามารถใช้งานได้ตัวอย่างเช่นจัดเตรียมข้อมูลที่แคช (ขึ้นอยู่กับชื่อตัวแปรของคุณฉันคิดว่ามันอาจไม่ได้ใช้งานหนัก สำหรับการใช้งานหนักคุณควรพิจารณาใช้ SQL แบบคลาสสิกโดยไม่ต้องสงสัย

หากคุณจะไปที่https://github.com/prowdsponsor/esqueletoคุณจะพบว่า:

คุณลักษณะ SQL บางอย่างนั้นมีให้ใช้งาน แต่ส่วนใหญ่สามารถเพิ่มได้ง่าย (โดยเฉพาะฟังก์ชั่น)

เพื่อให้คุณสามารถลองขอคุณสมบัติใหม่ โชคดี!


คุณมีลิงค์ไปยังแหล่งที่มาของสิ่งนี้หรือไม่? ฉันยินดีที่จะมอบรางวัลถ้ามีใครสามารถยืนยันได้ว่านี่เป็นคำตอบที่ถูกต้องหรือคุณสามารถให้เอกสารบางประเภทได้
เทคเมธี

@ NotoriousPet0 หากคุณไปที่เว็บไซต์ Haskellคุณจะพบรายการตัวอย่างที่สมบูรณ์และใช้เคสและไม่มีกรณีใดที่ใช้รายการหลายมิติแม้แต่ "การรวมภายใน" หากคุณค้นหา "กลุ่มตาม" ที่นั่นคุณจะพบว่ามันสามารถใช้สำหรับการปิดล้อมคอลัมน์หลายคอลัมน์ใน tuple หรือเรียงลำดับตามฟังก์ชันการรวมเพิ่มเติม นอกจากนี้ยังกล่าวว่ามีนักพัฒนาที่พยายามที่จะทำให้ Esqueleto เป็นความยืดหยุ่นมากพอที่จะสนับสนุนการสอบถามใด ๆ เพื่อให้คุณสามารถขอขยายเพิ่มเติมที่นี่
Kainax
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.