Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Als leverancier wil ik niet een exact totaal aantal resultaten hoeven te berekenen #2284

Open
joeribekker opened this issue Jul 11, 2023 · 8 comments
Assignees
Milestone

Comments

@joeribekker
Copy link
Collaborator

...zodat de performance van een list-endpoint acceptabel blijft.

Bij recente performance tests van Open Zaak blijkt dat met een miljoen zaken en documenten, de performance een flinke knauw krijgt door het berekenen van het totaal aantal resultaten in een lijst-weergave. Het gaat om count in de metadata van de resultaten bij elke gepagineerde list-endpoint

{
  "count": 1019561,
  "next": "http://example.com",
  "previous": "http://example.com",
  "results": [
  ]
}

Het berekenen van deze count duurt nog veel langer als je rekening houdt met allerlei autorisaties binnen de resultaten.

Om deze reden willen we de count benaderen of maximeren, zodat niet het exacte totaal hoeft te worden berekend. We stellen daarom voor om een extra attribuut toe te voegen countExact:

countExact:
  description: 'Geeft aan of de `count` exact is, of dat deze wegens 
  performance doeleinden niet exact berekend is.'

Het gedrag kan dan zijn:

  1. Stel er zijn 556 resultaten en er worden 50 resultaten per pagina getoond.
  2. Maximeer de count voor de eerste pagina op 500.
  3. Als er meer dan 500 resultaten zijn, staat countExact op false
  4. Pagina 1 toont dan count van 500 (resultaten 1-50)
  5. Als je naar de volgende pagina gaat (resultaten 51-100), increase dan de count met het aantal resultaten van de vorige pagina's (50).
    Pagina 2 heeft dus een count van 550 en countExact blijft false
  6. Pagina 3 heeft een count van 556 (de max) en countExact staat dan weer op true

Op deze manier weet een client altijd dat de 500 die hij zag op pagina 1, niet het exacte totaal hoeft te zijn. Maar, als de client door de pagina's heen bladert, dan komt hij op een gegeven moment wel het exacte aantal tegen.

{
  "count": 500,
  "countExact": false,
  "next": "http://example.com",
  "previous": "http://example.com",
  "results": [
  ]
}

Achtergrond bij redenatie
Voor echte mensen, is dit geen probleem. Wie gaat er ooit naar Google pagina 2 of 3? De kans is klein dat een mens wil zien dat er meer dan 10 pagina's zijn. Maar, stel je toont op in een applicatie de paginering: [ 1 2 3 4 5 6 7 8 9 10 ] en iemand klikt op pagina 10, dan wordt de count uit de API dus groter en zou je pagina 10 t/m 20 ook navigeerbaar kunnen maken.

Voor automatische clients, die echt alle pagina's willen doorlopen, werkt dit patroon ook MITS ze niet aan het begin van de for-loop bepalen hoeveel pagina's ze moeten doorlopen. Ze moeten rekening houden met de countExact of via een while-loop alles doorlopen.

Naar onze mening is dit "redelijk" backwards compatible, maar de MITS hierboven geeft al aan dat het niet 100% is.

@michielverhoef michielverhoef added this to the Zaken API 1.6 milestone Jul 11, 2023
@michielverhoef michielverhoef changed the title Als leverancier wil ik niet een exact totaal aantal resultaten te berekenen Als leverancier wil ik niet een exact totaal aantal resultaten hoeven te berekenen Jul 11, 2023
@HenriKorver
Copy link
Collaborator

HenriKorver commented Jul 11, 2023

Naar onze mening is dit "redelijk" backwards compatible, maar de MITS hierboven geeft al aan dat het niet 100% is.

We zouden een gelijknamige query parameter kunnen toevoegen aan de GET-operatie. Bijvoorbeeld,

GET /zaken?countExact=false

zodat de consumer zelf kan aangeven of die wel of niet met een exacte count wil werken. Op deze manier is de nieuwe feature alleen een (mogelijke) breaking change voor die applicaties die er echt gebruik van willen maken.

De default is countExact=true zodat consumers die geen gebruik willen maken van de nieuwe feature er gegarandeerd geen last van hebben.

@HenriKorver
Copy link
Collaborator

HenriKorver commented Jul 11, 2023

Maximeer de count voor de eerste pagina op 500.

Is dit getal (500) volledig random? Of zijn er tips en trucs om een goede schatting te geven. Google lijkt namelijk een (realistische) schatting van het aantal resultaten te geven.

@joeribekker
Copy link
Collaborator Author

De default is countExact=true zodat consumers die geen gebruik willen maken van de nieuwe feature er gegarandeerd geen last van hebben.

Lijkt me prima idee. Performance metingen ga ik dan wel met countExact=false doen :)

Is dit getal (500) volledig random?

Ik had zelf 10x de paginagrootte (10x50) in gedachten zodat je eventueel 1 t/m 10 als pagina navigatie kan opnemen.

Of zijn er tips en trucs om een goede schatting te geven.

Je zou iets met caching kunnen doen, maar dat gaat al niet meer werken als je filters opgeeft of met permissies zit.

Google lijkt namelijk een (realistische) schatting van het aantal resultaten te geven.

Valt tegen vind ik. Je kan nooit controleren of die schatting uberhaupt ergens op slaat. Daarnaast zijn wij ook geen Google hehe. Bij Gmail zie je dat ze niet eens een schatting geven zodra je filtert:

image

Terwijl er maar 53 zijn hehe:

image

@HenriKorver
Copy link
Collaborator

HenriKorver commented Jul 12, 2023

In de OAS van de Zaken API heb ik deze feature alvast uitgewerkt voor de operatie GET /zaken, zie redoc. Als dit naar wens is kan ik deze feature kopiëren naar alle plekken binnen de Zaken API waar paginering een rol speelt.

@HenriKorver
Copy link
Collaborator

Ik neem aan dat we deze nieuwe feature ook willen toevoegen aan de andere ZGW API's?

@joeribekker
Copy link
Collaborator Author

Wellicht kunnen we de attributen count en countExact ook meteen deprecated maken.

De NL API Strategie zegt er ook over:

NOTE: Providing the total count and/or last page of a collection should be considered carefully, since this may have a considerable impact on performance when dealing with larger collections. Therefore, providing such information or links is generally discouraged. Most often, this is not a problem since this does not add significant value for end users. Most modern user interfaces provide next/prev links only (e.g. a load more control).

Bron: https://docs.geostandaarden.nl/api/API-Strategie-ext/#pagination

Over NL API Strategie gesproken, ik heb dit onderwerp ook nog maar eens opgegooid aldaar: Geonovum/KP-APIs#605

@michielverhoef
Copy link
Collaborator

Zie ook #2140

@HenriKorver
Copy link
Collaborator

PR #2484 opgestart voor het oplossen van dit issue.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

3 participants