Ho creato una raccolta many-to-many con Slick 3.0, ma sto cercando di recuperare i dati nel modo desiderato.Slick 3.0 query many-to-many con join come iterable
C'è una relazione molti-a-molti tra Eventi e Interessi. Qui sono le mie tabelle:
case class EventDao(title: String,
id: Option[Int] = None)
class EventsTable(tag: Tag)
extends Table[EventDao](tag, "events") {
def id = column[Int]("event_id", O.PrimaryKey, O.AutoInc)
def title = column[String]("title")
def * = (
title,
id.?) <> (EventDao.tupled, EventDao.unapply)
def interests = EventInterestQueries.query.filter(_.eventId === id)
.flatMap(_.interestFk)
}
object EventQueries {
lazy val query = TableQuery[EventsTable]
val findById = Compiled { k: Rep[Int] =>
query.filter(_.id === k)
}
}
Ecco EventsInterests:
case class EventInterestDao(event: Int, interest: Int)
class EventsInterestsTable(tag: Tag)
extends Table[EventInterestDao](tag, "events_interests") {
def eventId = column[Int]("event_id")
def interestId = column[Int]("interest_id")
def * = (
eventId,
interestId) <> (EventInterestDao.tupled, EventInterestDao.unapply)
def eventFk = foreignKey("event_fk", eventId, EventQueries.query)(e => e.id)
def interestFk = foreignKey("interest_fk", interestId, InterestQueries.query)(i => i.id)
}
object EventInterestQueries {
lazy val query = TableQuery[EventsInterestsTable]
}
E infine Interessi:
case class InterestDao(name: String,
id: Option[Int] = None)
class InterestsTable(tag: Tag)
extends Table[InterestDao](tag, "interests") {
def id = column[Int]("interest_id", O.PrimaryKey, O.AutoInc)
def name = column[String]("name")
def name_idx = index("idx_name", name, unique = true)
def * = (
name,
id.?) <> (InterestDao.tupled, InterestDao.unapply)
def events = EventInterestQueries.query.filter(_.interestId === id)
.flatMap(_.eventFk)
}
object InterestQueries {
lazy val query = TableQuery[InterestsTable]
val findById = Compiled { k: Rep[Int] =>
query.filter(_.id === k)
}
}
posso interrogare e recuperare tuple di (event.name, interessi) con il seguente :
val eventInterestQuery = for {
event <- EventQueries.query
interest <- event.interests
} yield (event.title, interest.name)
Await.result(db.run(eventInterestQuery.result).map(println), Duration.Inf)
Quindi questo è quello che attualmente ho.
Quello che voglio è quello di essere in grado di compilare una classe caso come:
case class EventDao(title: String,
interests: Seq[InterestDao],
id: Option[Int] = None)
Il guaio è che se aggiorno la mia classe caso come questo, si scombina il mio def *
proiezione EventsTable
. Inoltre, dovrò rinominare il filtro EventsTable.interests
con qualcosa come EventsTable.interestIds
che è un po 'brutto ma potrei vivere con se necessario.
Inoltre, non riesco a trovare un modo di scrivere una query for
che produce (event.name, Seq(interest.name))
. Ad ogni modo, è solo un trampolino di lancio per me essere in grado di cedere una tupla (EventDao, Seq(InterestDao))
che è ciò che voglio davvero tornare.
Qualcuno sa come posso ottenere queste cose? Voglio anche essere in grado di "prendere" un certo numero di Interessi, quindi per alcune query tutti verrebbero restituiti, ma per altri solo i primi 3 sarebbero.
È impazzito, è necessario inviare * l'intero set di risultati non raggruppato * sul filo * e quindi * sul client. Per piccoli set di risultati, certo, non un grosso problema, ma l'invio di record di 100K + che potrebbero facilmente essere raggruppati a livello di database, wow. – virtualeyes
@virtualeyes: quale approccio consiglieresti allora? – LuGo
@virtualeyes Non ho letto la domanda completa ma il gruppo non può essere usato direttamente nella query? Come descritto nella documentazione: http://slick.typesafe.com/doc/3.0.0/queries.html#aggregation – Ixx