Xử lý các loại danh sách với Esqueleto


144

Tôi có các kiểu dữ liệu được định nghĩa là:

data ComitteeView = CommitteeView { committeeId :: CommitteeId
                                  , committeeMembers :: [Person] 
                                  }

data CommitteesView = CommitteesView { committeeView :: [CommitteeView] }

Bây giờ, khi nó đứng, tôi có một mô hình liên tục được định nghĩa là:

Person
  name  Text

Committee
  name  Text

CommitteePerson
  personId    PersonId
  committeeId CommitteeId

Tôi có thể dễ dàng tạo một truy vấn để điền vào một BoardView, sử dụng Esqueleto. Nó sẽ đi một cái gì đó như thế này:

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

Bây giờ, hãy xem xét vấn đề dân cư CommitteesView. Về nguyên tắc, chúng tôi có đủ dữ liệu để cư trú bằng cách chạy truy vấn con trong truy vấn trên. Được rồi, đủ công bằng. Bây giờ làm thế nào tôi có thể sử dụng "nhóm theo Haskell-list" như group bytrong SQL? Làm thế nào tôi có thể gấp các hàng để tôi có thể kết thúc với một danh sách các danh sách người?

Tôi có ấn tượng rằng esqueletokhông thể xử lý trường hợp như vậy (nghĩa là, nó không có một tổ hợp sẽ làm điều đó). Và cơ sở dữ liệu cơ bản của tôi rõ ràng không hỗ trợ danh sách Haskell dưới dạng cột. Nhưng, chắc chắn, tôi không thể là người duy nhất phải đối mặt với vấn đề này. Một chiến lược hiệu quả là gì? Gấp một danh sách n của danh sách vào danh sách n? Hoặc chạy n+1truy vấn? Có sự lựa chọn nào khác không?


2
Bạn đã nhìn Data.List.groupBychưa
cdk

@cdk: Vâng, đó là những gì tôi đã đi với. Nó được lông đáng ngạc nhiên, mặc dù.
Tên của

Câu trả lời:


2

Esqueleto KHÔNG có nghĩa là xử lý danh sách các danh sách con (danh sách đa chiều) ra khỏi hộp! Data.List.groupByđó là 'cdk' khuyên bạn chỉ có thể tự liệt kê danh sách, nhưng không phải những gì bạn đang yêu cầu.

Đối với trường hợp của bạn, tôi sẽ khuyên bạn nên sử dụng một truy vấn SQL cổ điển. Bạn có thể chạy các truy vấn n + 1, nhưng chỉ làm điều đó nếu nó hiếm và không thường sử dụng được, ví dụ như chuẩn bị dữ liệu được lưu trong bộ nhớ cache (dựa trên tên biến của bạn, tôi cho rằng nó có thể không được sử dụng nhiều và nó đáng để thử). Để sử dụng nhiều, bạn nên xem xét sử dụng SQL cổ điển mà không có nghi ngờ gì.

Nếu bạn sẽ truy cập https://github.com/prowdsponsor/esqueleto, bạn sẽ thấy rằng:

Không phải tất cả các tính năng SQL đều có sẵn, nhưng hầu hết chúng có thể dễ dàng thêm vào (đặc biệt là các hàm).

vì vậy bạn có thể thử yêu cầu một tính năng mới. Chúc may mắn!


Bạn có một liên kết đến một nguồn về điều này? Tôi sẽ rất vui khi trao tiền thưởng nếu ai đó có thể xác minh đây là câu trả lời đúng hoặc bạn có thể cung cấp một số loại tài liệu.
Công nghệ tiết kiệm

@ NotoriousPet0 Nếu bạn truy cập trang web haskell, bạn sẽ tìm thấy danh sách đầy đủ các ví dụ và trường hợp sử dụng và không ai trong số họ sử dụng danh sách đa chiều, thậm chí là "tham gia nội bộ". Nếu bạn tìm kiếm một "nhóm theo" ở đó, bạn sẽ thấy rằng nó có thể được sử dụng để bao quanh nhiều cột trong một tuple hoặc sắp xếp theo hàm tổng hợp bổ sung. Người ta cũng nói rằng các nhà phát triển cố gắng làm cho Esqueleto linh hoạt hơn để hỗ trợ bất kỳ truy vấn nào, vì vậy bạn có thể yêu cầu gia hạn thêm ở đây .
Kainax
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.