2015-12-21 5 views
5

Mit Slick 3.1, wie kombiniere ich mehrere Abfragen in einer einzigen Abfrage für den gleichen Typ? Dies ist kein Join oder eine Union, aber Abfrage "Segmente" zu kombinieren, um eine einzelne Abfrageanforderung zu erstellen. Diese "Segmente" können jede individuell gültige Anfrage sein.Slick-Abfragen in einzelne Abfrage kombinieren

val query = TableQuery[SomeThingValid] 

// build up pieces of the query in various parts of the application logic 
val q1 = query.filter(_.value > 10) 
val q2 = query.filter(_.value < 40) 
val q3 = query.sortBy(_.date.desc) 
val q4 = query.take(5) 

// how to combine these into a single query ? 
val finalQ = ??? q1 q2 q3 q4 ??? 

// in order to run in a single request 
val result = DB.connection.run(finalQ.result) 

EDIT: die erwartete SQL etwas sein sollte:

SELECT * FROM "SomeThingValid" WHERE "SomeThingValid"."value" > 10 AND "SomeThingValid"."valid" < 40 ORDER BY "MemberFeedItem"."date" DESC LIMIT 5 
+1

Ich bin mir nicht ganz sicher, was Sie als Ergebnis erwarten. Ich denke, ich muss fragen: Wie würdest du das in SQL machen? –

+0

@ PatrykĆwiek mit Beispiel erwartet sql aktualisiert – IUnknown

Antwort

4
val q1 = query.filter(_.value > 10) 
val q2 = q1.filter(_.value < 40) 
val q3 = q2.sortBy(_.date.desc) 
val q4 = q3.take(5) 

Ich glaube, Sie so etwas wie die oben tun sollte (und laufen um Query s), aber wenn Sie darauf bestehen, um Abfrage „Segmente“ auf vorbei, so etwas wie dies funktionieren könnte:

type QuerySegment = Query[SomeThingValid, SomeThingValid, Seq] => Query[SomeThingValid, SomeThingValid, Seq] 

val q1: QuerySegment = _.filter(_.value > 10) 
val q2: QuerySegment = _.filter(_.value < 40) 
val q3: QuerySegment = _.sortBy(_.date.desc) 
val q4: QuerySegment = _.take(5) 

val finalQ = Function.chain(Seq(q1, q2, q3, q4))(query) 
+0

Ja, ich kann Klauseln zu einer Abfrage hinzufügen, das Ziel war es, verschiedene Abfragen, die erstellt wurden und bringen sie zusammen zu generieren sql wie im Beispiel. – IUnknown

+0

@IUnknown siehe meine Bearbeitung. – danielnixon

+0

schön, danke - das ist genau das, was ich suchte – IUnknown

0

habe ich dieses "Muster" mit slick2.0 verwendet

val query = TableQuery[SomeThingValid] 

val flag1, flag3 = false 
val flag2, flag4 = true 

val bottomFilteredQuery = if(flag1) query.filter(_.value > 10) else query 
val topFilteredQuery = if(flag2) bottomFilteredQuery.filter(_.value < 40) else bottomFilteredQuery 
val sortedQuery = if(flag3) topFilteredQuery.soryBy(_.date.desc) else topFilteredQuery 
val finalQ = if(flag4) sortedQuery.take(5) else sortedQuery 
+0

dies funktioniert nicht in meinem Fall, weil die eingehende Abfrage eine nicht-deterministische arbitrary-Set sind. – IUnknown

-1

Ich denke, es sollte funktionieren . Aber ich habe es noch nicht getestet.

val users = TableQuery[Users] 
val filter1: Query[Users, User, Seq] = users.filter(condition1) 
val filter2: Query[Users, User, Seq] = users.filter(condition2) 
(filter1 ++ filter2).result.headOption