Skip to content

Commit de4cfd6

Browse files
committed
Query med ferdigstiltDato. Tuner litt på indekser.
1 parent ea34d64 commit de4cfd6

File tree

7 files changed

+115
-39
lines changed

7 files changed

+115
-39
lines changed

src/main/kotlin/no/nav/k9/los/nyoppgavestyring/query/db/AktivOppgaveQuerySqlBuilder.kt

+5-6
Original file line numberDiff line numberDiff line change
@@ -128,11 +128,6 @@ class AktivOppgaveQuerySqlBuilder(
128128

129129
val index = queryParams.size + orderByParams.size
130130
when (feltkode) {
131-
"sistEndret" -> {
132-
query += "${combineOperator.sql} o.endret_tidspunkt ${operator.sql} (timestamp :sistEndret$index)) "
133-
queryParams["sistEndret$index"] = feltverdi
134-
}
135-
136131
"kildeområde" -> {
137132
query += "${combineOperator.sql} o.kildeomrade ${operator.sql} (:kildeomrade$index) "
138133
queryParams["kildeomrade$index"] = feltverdi
@@ -179,7 +174,11 @@ class AktivOppgaveQuerySqlBuilder(
179174
}
180175
}
181176

182-
else -> log.warn("Håndterer ikke filter for $feltkode")
177+
"oppgavestatus" -> {
178+
// Ignorerer felt, siden det er håndtert spesielt
179+
}
180+
181+
else -> log.warn("Håndterer ikke filter for $feltkode. Legg til i ignorering hvis feltet håndteres spesielt.")
183182
}
184183
}
185184

src/main/kotlin/no/nav/k9/los/nyoppgavestyring/query/db/PartisjonertOppgaveQuerySqlBuilder.kt

+16-8
Original file line numberDiff line numberDiff line change
@@ -17,18 +17,20 @@ import no.nav.k9.los.spi.felter.SqlMedParams
1717
import no.nav.k9.los.spi.felter.TransientFeltutleder
1818
import no.nav.k9.los.spi.felter.WhereInput
1919
import org.slf4j.LoggerFactory
20+
import java.time.LocalDate
2021
import java.time.LocalDateTime
2122

2223
class PartisjonertOppgaveQuerySqlBuilder(
2324
val felter: Map<OmrådeOgKode, OppgavefeltMedMer>,
2425
oppgavestatusFilter: List<Oppgavestatus>,
2526
val now: LocalDateTime,
26-
private val ferdigstiltDato: LocalDateTime? = null,
27+
private val ferdigstiltDato: LocalDate? = null,
2728
) : OppgaveQuerySqlBuilder {
2829
private val log = LoggerFactory.getLogger(PartisjonertOppgaveQuerySqlBuilder::class.java)
2930

3031
private val oppgavestatusPlaceholder: String = InClauseHjelper.tilParameternavn(oppgavestatusFilter, "status")
31-
private val ferdigstiltDatoBetingelse = if (ferdigstiltDato != null) " AND ov.ferdigstilt_dato = :ferdigstilt_dato " else ""
32+
private val ferdigstiltDatoBetingelseOppgavefeltverdi = if (ferdigstiltDato != null) " AND ov.ferdigstilt_dato = :ferdigstilt_dato " else ""
33+
private val ferdigstiltDatoBetingelseOppgave = if (ferdigstiltDato != null) " AND o.ferdigstilt_dato = :ferdigstilt_dato " else ""
3234

3335
private var selectPrefix = """
3436
SELECT o.oppgave_ekstern_id, o.oppgave_ekstern_versjon
@@ -39,7 +41,7 @@ class PartisjonertOppgaveQuerySqlBuilder(
3941
private var query = ("""
4042
FROM oppgave_v3_part o
4143
LEFT JOIN oppgave_pep_cache opc ON (opc.kildeomrade = 'K9' AND o.oppgave_ekstern_id = opc.ekstern_id)
42-
WHERE o.oppgavestatus in ($oppgavestatusPlaceholder) $ferdigstiltDatoBetingelse
44+
WHERE o.oppgavestatus in ($oppgavestatusPlaceholder) $ferdigstiltDatoBetingelseOppgave
4345
""").trimIndent()
4446

4547
private val filtrerReserverteOppgaver = """
@@ -82,6 +84,9 @@ class PartisjonertOppgaveQuerySqlBuilder(
8284
putAll(queryParams)
8385
putAll(orderByParams)
8486
putAll(oppgavestatusParams)
87+
if (ferdigstiltDato != null) {
88+
put("ferdigstilt_dato", ferdigstiltDato)
89+
}
8590
}
8691
}
8792

@@ -150,7 +155,11 @@ class PartisjonertOppgaveQuerySqlBuilder(
150155
}
151156
}
152157

153-
else -> log.warn("Håndterer ikke filter for $feltkode")
158+
"ferdigstiltDato", "oppgavestatus" -> {
159+
// Ignorerer felter, siden de er håndtert spesielt
160+
}
161+
162+
else -> log.warn("Håndterer ikke filter for $feltkode. Legg til i ignorering hvis feltet håndteres spesielt.")
154163
}
155164
}
156165

@@ -190,7 +199,7 @@ class PartisjonertOppgaveQuerySqlBuilder(
190199
${combineOperator.sql} ${if (operator.negasjonAv != null) "NOT" else ""} EXISTS (
191200
SELECT 1
192201
FROM oppgavefelt_verdi_part ov
193-
WHERE ov.oppgavestatus in ($oppgavestatusPlaceholder) $ferdigstiltDatoBetingelse
202+
WHERE ov.oppgavestatus in ($oppgavestatusPlaceholder) $ferdigstiltDatoBetingelseOppgavefeltverdi
194203
AND ov.oppgave_ekstern_id = o.oppgave_ekstern_id
195204
AND ov.oppgave_ekstern_versjon = o.oppgave_ekstern_versjon
196205
AND ov.omrade_ekstern_id = :feltOmrade$index
@@ -247,7 +256,7 @@ class PartisjonertOppgaveQuerySqlBuilder(
247256
${combineOperator.sql}$invertertOperator EXISTS (
248257
SELECT 1
249258
FROM oppgavefelt_verdi_part ov
250-
WHERE ov.oppgavestatus in ($oppgavestatusPlaceholder) $ferdigstiltDatoBetingelse
259+
WHERE ov.oppgavestatus in ($oppgavestatusPlaceholder) $ferdigstiltDatoBetingelseOppgavefeltverdi
251260
AND ov.oppgave_ekstern_id = o.oppgave_ekstern_id
252261
AND ov.oppgave_ekstern_versjon = o.oppgave_ekstern_versjon
253262
AND ov.omrade_ekstern_id = :feltOmrade$index
@@ -291,7 +300,6 @@ class PartisjonertOppgaveQuerySqlBuilder(
291300

292301
orderByParams.putAll(
293302
mapOf(
294-
"ferdigstilt_dato" to ferdigstiltDato,
295303
"orderByfeltOmrade$index" to feltområde,
296304
"orderByfeltkode$index" to feltkode
297305
)
@@ -303,7 +311,7 @@ class PartisjonertOppgaveQuerySqlBuilder(
303311
, (
304312
SELECT $verdifelt
305313
FROM oppgavefelt_verdi_part ov
306-
WHERE ov.oppgavestatus in ($oppgavestatusPlaceholder) $ferdigstiltDatoBetingelse
314+
WHERE ov.oppgavestatus in ($oppgavestatusPlaceholder) $ferdigstiltDatoBetingelseOppgavefeltverdi
307315
AND ov.oppgave_ekstern_id = o.oppgave_ekstern_id
308316
AND ov.oppgave_ekstern_versjon = o.oppgave_ekstern_versjon
309317
AND ov.omrade_ekstern_id = :orderByfeltOmrade$index

src/main/kotlin/no/nav/k9/los/nyoppgavestyring/query/mapping/OppgaveQueryToSqlMapper.kt

+41-4
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@ import no.nav.k9.los.nyoppgavestyring.mottak.oppgave.Oppgavestatus
44
import no.nav.k9.los.nyoppgavestyring.query.QueryRequest
55
import no.nav.k9.los.nyoppgavestyring.query.db.*
66
import no.nav.k9.los.nyoppgavestyring.query.dto.query.*
7+
import java.time.LocalDate
78
import java.time.LocalDateTime
89

910
object OppgaveQueryToSqlMapper {
@@ -14,7 +15,10 @@ object OppgaveQueryToSqlMapper {
1415
): OppgaveQuerySqlBuilder {
1516
val oppgavestatusFilter = traverserFiltereOgFinnOppgavestatusfilter(request)
1617
return when {
17-
oppgavestatusFilter.isEmpty() || oppgavestatusFilter.contains(Oppgavestatus.LUKKET) -> PartisjonertOppgaveQuerySqlBuilder(felter, oppgavestatusFilter, now)
18+
oppgavestatusFilter.isEmpty() || oppgavestatusFilter.contains(Oppgavestatus.LUKKET) -> {
19+
PartisjonertOppgaveQuerySqlBuilder(felter, oppgavestatusFilter, now,
20+
traverserFiltereOgFinnFerdigstiltDatofilter(request))
21+
}
1822
else -> AktivOppgaveQuerySqlBuilder(felter, oppgavestatusFilter, now)
1923
}
2024
}
@@ -49,7 +53,12 @@ object OppgaveQueryToSqlMapper {
4953

5054
fun traverserFiltereOgFinnOppgavestatusfilter(queryRequest: QueryRequest): List<Oppgavestatus> {
5155
val statuser = mutableSetOf<Oppgavestatus>()
52-
rekursivtSøk(queryRequest.oppgaveQuery.filtere, statuser)
56+
rekursivtSøk(
57+
queryRequest.oppgaveQuery.filtere,
58+
statuser,
59+
{ verdi -> Oppgavestatus.fraKode(verdi.toString()) },
60+
{ filter -> filter.kode == "oppgavestatus" }
61+
)
5362

5463
//dette parameteret brukes av index på oppgavefeltverdi. Spørringer som ser på lukkede oppgaver er ikke indekserte, og vil være trege
5564
//Dersom spørringen filterer på oppgavestatus, så matcher vi det.
@@ -61,7 +70,35 @@ object OppgaveQueryToSqlMapper {
6170
}
6271
}
6372

64-
private fun rekursivtSøk(
73+
fun traverserFiltereOgFinnFerdigstiltDatofilter(queryRequest: QueryRequest): LocalDate? {
74+
val datoer = mutableSetOf<LocalDate>()
75+
rekursivtSøk(
76+
queryRequest.oppgaveQuery.filtere,
77+
datoer,
78+
{ verdi -> LocalDate.parse(verdi.toString()) },
79+
{ filter -> filter.kode == "ferdigstiltDato" }
80+
)
81+
82+
//dette parameteret brukes av index på oppgavefeltverdi. Spørringer som ser på lukkede oppgaver er ikke indekserte, og vil være trege
83+
return datoer.firstOrNull()
84+
}
85+
86+
private fun <T> rekursivtSøk(
87+
filtere: List<Oppgavefilter>,
88+
verdierFunnet: MutableSet<T>,
89+
mapper: (Any?) -> T,
90+
betingelse: (FeltverdiOppgavefilter) -> Boolean
91+
) {
92+
for (filter in filtere) {
93+
if (filter is FeltverdiOppgavefilter && betingelse(filter)) {
94+
verdierFunnet.addAll(filter.verdi.map { verdi -> mapper(verdi) })
95+
} else if (filter is CombineOppgavefilter) {
96+
rekursivtSøk(filter.filtere, verdierFunnet, mapper, betingelse)
97+
}
98+
}
99+
}
100+
101+
/*private fun rekursivtSøk(
65102
filtere: List<Oppgavefilter>,
66103
statuser: MutableSet<Oppgavestatus>
67104
) {
@@ -72,7 +109,7 @@ object OppgaveQueryToSqlMapper {
72109
rekursivtSøk(filter.filtere, statuser)
73110
}
74111
}
75-
}
112+
}*/
76113

77114
private fun håndterFiltere(
78115
queryBuilder: OppgaveQuerySqlBuilder,

src/main/kotlin/no/nav/k9/los/nyoppgavestyring/visningoguttrekk/nøkkeltall/ferdigstilteperenhet/FerdigstiltePerEnhetService.kt

+7-1
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@ import kotlinx.coroutines.CoroutineScope
44
import kotlinx.coroutines.Dispatchers
55
import kotlinx.coroutines.launch
66
import no.nav.k9.los.domene.modell.FagsakYtelseType
7+
import no.nav.k9.los.nyoppgavestyring.mottak.oppgave.Oppgavestatus
78
import no.nav.k9.los.nyoppgavestyring.query.OppgaveQueryService
89
import no.nav.k9.los.nyoppgavestyring.query.QueryRequest
910
import no.nav.k9.los.nyoppgavestyring.query.dto.query.FeltverdiOppgavefilter
@@ -163,7 +164,12 @@ class FerdigstiltePerEnhetService(
163164
}
164165
add(
165166
FeltverdiOppgavefilter(
166-
"K9", "ferdigstiltTidspunkt", FeltverdiOperator.EQUALS.name, listOf(dato.toString())
167+
null, "oppgavestatus", FeltverdiOperator.EQUALS.name, listOf(Oppgavestatus.LUKKET.kode)
168+
)
169+
)
170+
add(
171+
FeltverdiOppgavefilter(
172+
null, "ferdigstiltDato", FeltverdiOperator.EQUALS.name, listOf(dato.toString())
167173
)
168174
)
169175
}

src/main/resources/migreringer/V1.0_0078__partisjoner_ofv.sql

+12-16
Original file line numberDiff line numberDiff line change
@@ -59,25 +59,21 @@ CREATE TABLE oppgavefelt_verdi_lukket_2025_part
5959

6060
-- Indekser
6161
create index ofv_oppgave_id_idx on oppgavefelt_verdi_part(oppgave_ekstern_id);
62-
create index ofv_aapen_venter_verdi_idx on oppgavefelt_verdi_aapen_venter_part(omrade_ekstern_id, feltdefinisjon_ekstern_id, verdi, oppgave_ekstern_id);
63-
create index ofv_aapen_venter_verdi_bigint_idx on oppgavefelt_verdi_aapen_venter_part(omrade_ekstern_id, feltdefinisjon_ekstern_id, verdi_bigint, oppgave_ekstern_id);
64-
create index ofv_aapen_venter_idx on oppgavefelt_verdi_aapen_venter_part(omrade_ekstern_id, feltdefinisjon_ekstern_id, oppgave_ekstern_id);
62+
create index ofv_aapen_venter_verdi_idx on oppgavefelt_verdi_aapen_venter_part(oppgave_ekstern_id, feltdefinisjon_ekstern_id, verdi);
63+
create index ofv_aapen_venter_verdi_bigint_idx on oppgavefelt_verdi_aapen_venter_part(oppgave_ekstern_id, feltdefinisjon_ekstern_id, verdi_bigint) where verdi_bigint is not null;
6564
create index ofv_lukket_ferdigstilt_dato_idx on oppgavefelt_verdi_lukket_part(
66-
ferdigstilt_dato,
67-
omrade_ekstern_id,
65+
ferdigstilt_dato desc,
66+
oppgave_ekstern_id,
6867
feltdefinisjon_ekstern_id,
69-
verdi,
70-
oppgave_ekstern_id
71-
);
68+
verdi
69+
);
7270
create index ofv_lukket_verdi_idx on oppgavefelt_verdi_lukket_part(
73-
omrade_ekstern_id,
71+
oppgave_ekstern_id,
7472
feltdefinisjon_ekstern_id,
75-
verdi,
76-
oppgave_ekstern_id
77-
);
73+
verdi
74+
);
7875
create index ofv_lukket_verdi_bigint_idx on oppgavefelt_verdi_lukket_part(
79-
omrade_ekstern_id,
76+
oppgave_ekstern_id,
8077
feltdefinisjon_ekstern_id,
81-
verdi,
82-
oppgave_ekstern_id
83-
);
78+
verdi_bigint
79+
) where verdi_bigint is not null;

src/test/kotlin/no/nav/k9/los/nyoppgavestyring/OppgaveTestDataBuilder.kt

+5-4
Original file line numberDiff line numberDiff line change
@@ -67,21 +67,21 @@ class OppgaveTestDataBuilder(
6767
}
6868

6969

70-
fun lagOgLagre(status: Oppgavestatus = Oppgavestatus.AAPEN): OppgaveV3 {
70+
fun lagOgLagre(status: Oppgavestatus = Oppgavestatus.AAPEN, endretTidspunkt: LocalDateTime = LocalDateTime.now()): OppgaveV3 {
7171
return transactionManager.transaction { tx ->
72-
val oppgave = lag(status)
72+
val oppgave = lag(status, endretTidspunkt = endretTidspunkt)
7373
oppgaverepo.nyOppgaveversjon(oppgave, tx)
7474
oppgave
7575
}
7676
}
7777

78-
fun lag(status: Oppgavestatus = Oppgavestatus.AAPEN, reservasjonsnøkkel: String = "", eksternVersjon: String? = null): OppgaveV3 {
78+
fun lag(status: Oppgavestatus = Oppgavestatus.AAPEN, reservasjonsnøkkel: String = "", eksternVersjon: String? = null, endretTidspunkt: LocalDateTime = LocalDateTime.now()): OppgaveV3 {
7979
return OppgaveV3(
8080
eksternId = oppgaveFeltverdier[FeltType.BEHANDLINGUUID]?.verdi ?: UUID.randomUUID().toString(),
8181
eksternVersjon = eksternVersjon ?: eksternVersjonTeller++.toString(),
8282
oppgavetype = oppgavetype,
8383
status = status,
84-
endretTidspunkt = LocalDateTime.now(),
84+
endretTidspunkt = endretTidspunkt,
8585
kildeområde = område.eksternId,
8686
felter = oppgaveFeltverdier.values.toList(),
8787
reservasjonsnøkkel = reservasjonsnøkkel,
@@ -119,6 +119,7 @@ enum class FeltType(
119119
LØSBART_AKSJONSPUNKT("løsbartAksjonspunkt"),
120120
LIGGER_HOS_BESLUTTER("liggerHosBeslutter", tolkesSom = "boolean"),
121121
TID_FORSTE_GANG_HOS_BESLUTTER("tidFørsteGangHosBeslutter"),
122+
FERDIGSTILT_DATO("ferdigstiltDato", tolkesSom = "Timestamp", område = null),
122123
}
123124

124125
val felter: Map<OmrådeOgKode, OppgavefeltMedMer> = mapOf(

src/test/kotlin/no/nav/k9/los/nyoppgavestyring/query/OppgaveQueryTest.kt

+29
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@ import no.nav.k9.los.nyoppgavestyring.kodeverk.PersonBeskyttelseType
1818
import no.nav.k9.los.nyoppgavestyring.mottak.feltdefinisjon.FeltdefinisjonRepository
1919
import no.nav.k9.los.nyoppgavestyring.mottak.omraade.OmrådeRepository
2020
import no.nav.k9.los.nyoppgavestyring.mottak.oppgave.Oppgavestatus
21+
import no.nav.k9.los.nyoppgavestyring.mottak.oppgave.PartisjonertOppgaveId
2122
import no.nav.k9.los.nyoppgavestyring.pep.PepCache
2223
import no.nav.k9.los.nyoppgavestyring.pep.PepCacheRepository
2324
import no.nav.k9.los.nyoppgavestyring.pep.TestRepository
@@ -930,6 +931,34 @@ class OppgaveQueryTest : AbstractK9LosIntegrationTest() {
930931
assertThat(oppgaveQueryRepository.query(QueryRequest(query))).isEmpty()
931932
}
932933

934+
@Test
935+
fun `sjekk at ferdigstiltDato kan brukes som felt`() {
936+
val oppgaveTestDataBuilder = OppgaveTestDataBuilder()
937+
val oppgaveQueryRepository = OppgaveQueryRepository(dataSource, mockk<FeltdefinisjonRepository>())
938+
939+
// lager to oppgaver, en ferdigstilt i dag og en ferdigstilt 1. januar 2025
940+
oppgaveTestDataBuilder
941+
.lagOgLagre(
942+
status = Oppgavestatus.LUKKET,
943+
)
944+
val oppgaveLukketFørsteJanuar = oppgaveTestDataBuilder
945+
.lagOgLagre(
946+
status = Oppgavestatus.LUKKET,
947+
endretTidspunkt = LocalDateTime.of(2025, 1, 1, 0, 0, 0)
948+
)
949+
950+
val resultat = oppgaveQueryRepository.query(
951+
QueryRequest(
952+
OppgaveQuery(
953+
listOf(
954+
byggFilter(FeltType.FERDIGSTILT_DATO, FeltverdiOperator.EQUALS, "2025-01-01"),
955+
byggFilter(FeltType.OPPGAVE_STATUS, FeltverdiOperator.EQUALS, "LUKKET"),
956+
)
957+
)
958+
))
959+
assertThat(resultat).containsOnly(PartisjonertOppgaveId(oppgaveLukketFørsteJanuar.eksternId, oppgaveLukketFørsteJanuar.eksternVersjon))
960+
}
961+
933962
private fun lagOppgaveMedPepCache(
934963
kode6: Boolean = false,
935964
kode7: Boolean = false,

0 commit comments

Comments
 (0)