Liste türlerini Esqueleto ile işleme


144

Veri türleri olarak tanımlanmış var:

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

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

Şimdi, olduğu gibi, Kalıcı bir modelim var:

Person
  name  Text

Committee
  name  Text

CommitteePerson
  personId    PersonId
  committeeId CommitteeId

Esqueleto kullanarak bir CommissionView doldurmak için kolayca bir sorgu oluşturabilirsiniz. Böyle bir şeye giderdi:

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

Şimdi, nüfus problemini düşünün CommitteesView. Prensip olarak, yukarıdaki sorguda alt sorgu çalıştırarak doldurmak için yeterli veri alırız. Tamam, yeterince adil. Şimdi group bySQL'de olduğu gibi "Group by Haskell-list" i nasıl kullanabilirim ? Bir kişi listesiyle sonuçlanabilmek için satırları nasıl katlayabilirim?

esqueletoDavayı bu şekilde ele alamayacak izlenimi edindim (yani, bunu yapacak bir birleştirici yok). Temel veritabanım Haskell listelerini sütun olarak desteklemiyor. Ancak, elbette, bu sorunla karşılaşan tek kişi ben olamam. Etkili bir strateji nedir? Listelerin n listesini n listesine mi katlamak istiyorsunuz? Veya n+1sorgular mı çalıştırıyorsunuz ? Başka seçenek var mı?


2
Baktın mı Data.List.groupBy?
cdk

@cdk: Evet, işte böyle devam ediyordum. Yine de şaşırtıcı bir şekilde kıllı olur.
nomen

Yanıtlar:


2

Esqueleto edilir DEĞİL henüz kutudan çıktığı sublists kolu listesinde (çok boyutlu liste) anlamına! Data.List.groupBysize tavsiye edilen 'cdk' sadece kendisini listeleyebilir, ama ne istediğinizi değil.

Sizin durumunuz için klasik bir SQL sorgusu kullanmanızı ısrarla öneririm. N + 1 sorguları çalıştırabilirsiniz, ancak bunu yalnızca nadir ve genellikle kullanışlı bir işlev değilse, örneğin önbelleğe alınmış verileri hazırlar (değişken adlarınıza dayanarak, ağır kullanılmayabileceğini ve denemeye değer olduğunu düşünüyorum). Yoğun kullanım için klasik SQL'i şüphesiz kullanmayı düşünmelisiniz.

Https://github.com/prowdsponsor/esqueleto adresine gidecekseniz şunları bulacaksınız:

Tüm SQL özellikleri mevcut değildir, ancak çoğu kolayca eklenebilir (özellikle işlevler).

böylece yeni bir özellik istemeyi deneyebilirsiniz. İyi şanslar!


Bu konuda bir kaynağa bağlantınız var mı? Birisi bunun doğru cevap olduğunu doğrulayabilirse veya bir tür belge sağlayabilirseniz ödülü vermekten mutluluk duyacağım.
Tech Savant

@ NotoriousPet0 Haskell web sitesine giderseniz, örneklerin tam listesini ve vakaları bulacaksınız ve hiçbiri çok boyutlu listeler, hatta "iç birleşim" kullanmaz. Orada bir "gruplama ölçütü" araması yaparsanız, bunun bir demet içine birden çok sütun eklemek veya ek toplama işlevi ile sıralama yapmak için kullanılabileceğini görürsünüz. Ayrıca, geliştiricilerin Esqueleto'yu herhangi bir sorguyu destekleyecek kadar esnek hale getirmeye çalıştıklarını da söylüyor, böylece burada ek uzantı isteyebilirsiniz .
Kainax
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.