In deze serie technische artikelen nemen we je mee achter de schermen bij Walter. Dit is hoe we negen miljoen adressen binnen milliseconden doorzoeken.

Walter Living vertelt je alles wat er over een specifiek huis te weten valt, geplaatst in de context van buurt, wijk en stad.
Met Walter Living doe je een haarscherp bod op je volgende huis. Wij vertellen je alles wat er over een specifiek huis te weten valt, geplaatst in de context van buurt, wijk en stad. Om dat te doen combineren en analyseren we meerdere grote datasets in een paar seconden. Maar hoe doen we dat eigenlijk?
In deze serie technische artikelen nemen we je mee achter de schermen bij Walter, om een kijkje te geven in onze geografische datakeuken. In dit eerste deel: hoe doorzoek je zo snel mogelijk negen miljoen adressen?
De Basis Registratie Adressen en Gebouwen
Het Kadaster is verantwoordelijk voor de registratie van alle grond en vastgoed in Nederland. Zij houden bij wie de eigenaar is van elk stukje grond en van de gebouwen die op die grond staan. Deze informatie wordt vastgelegd in de Basisregistratie Adressen en Gebouwen, oftewel de BAG.
Omdat Walter Living over elk adres in Nederland iets wil zeggen, is het cruciaal om een lijst met alle adressen te hebben en up-to-date te houden. Het beginpunt van elke zoektocht bij Walter Living is namelijk een autocomplete zoekbalk die elk adres van Nederland binnen een paar tellen uit de lijst, de BAG, tevoorschijn tovert.
De uitdaging is dat het hier gaat om meer dan negen miljoen adressen. Hoe krijg je al deze data in een fatsoenlijk formaat ingelezen en hoe zorg je vervolgens dat je er betrouwbare zoekresultaten uit kan halen met minder dan een paar milliseconden latency?
Er zijn een paar specifieke uitdagingen aan dit probleem:
- De BAG is een open dataset die voor iedereen in Nederland gratis te gebruiken is. Helaas is het formaat niet gemaakt om doorzoekbaar te zijn in een webapplicatie. Er is dus wat magie nodig om de databestanden te converteren en importeren naar een bruikbaar formaat.
- Als de BAG-bestanden eenmaal zijn ingelezen, moeten ze worden geïndexeerd om de bestanden doorzoekbaar te maken. Dit is de eenvoudigste stap – met behulp van Elasticsearch en default index mappings komen we een heel eind.
- De grootste uitdaging is het daadwerkelijk doorzoeken van adressen. De conventies van adressen kunnen nogal verschillen tussen woonplaatsen, buurten en zelfs straten. Ondanks dappere pogingen van het Kadaster, zijn adressen in Nederland niet zo netjes en duidelijk aangeduid als je zou hopen.
Dataconversie en import
Het voorbereiden van meer dan negen miljoen XML-objecten om te importeren in PostgreSQL is niet bepaald onze hobby. Gelukkig hebben de knappe koppen van NLExtract open source tools beschikbaar gemaakt waarmee de ruwe BAG-bestanden van het Kadaster kunnen worden geconverteerd en geïmporteerd in een Postgres-database, compleet voorzien van de juiste PostGIS-informatie en indices. Ze bieden zelfs elke maand een compleet geprepareerde Postgres-dump aan die je direct in je eigen database kan inlezen.
Omdat wij nu alleen interesse hebben in het doorzoekbaar maken van alle adressen, beperken wij ons tot de bagactueel
tabel uit deze NLExtract dataset. Momenteel zijn dat 9.152.803 adressen in Nederland, om precies te zijn. Op naar de volgende stap: indexeren in Elasticsearch.
De uitdaging zit hem dan ook niet in het doorzoeken, maar in het stellen van de juiste vraag.
Indexeren in Elasticsearch
Negen miljoen records doorzoeken is een eitje voor Elasticsearch. De uitdaging zit hem dan ook niet in het doorzoeken, maar in het stellen van de juiste vraag. Omdat wij je helpen bij het doen van een haarscherp bod op je volgende huis, moeten we adressen kunnen vinden van woningen die te koop staan, bijvoorbeeld op Funda of JAAP.
We kwamen er al snel achter dat lang niet alle makelaars netjes de adressen uit de BAG gebruiken als ze een huis te koop aanbieden. Zo kan de “Dorpstraat 23-3 in Alphen aan den Rijn” online te vinden zijn als de “Dorpstraat 23-III in Alphen a/d Rijn”, of “Prinseneiland 12-H in Amsterdam” als “Prinseneiland 12-huis in A’dam”.
Onze Elasticsearch-index heeft dus een aardig setje filters en normalizers nodig om dit soort inconsistenties zo goed mogelijk te filteren, zodat we in de meeste gevallen een resultaat kunnen vinden voor je zoekopdracht. We doen al dit werk vóór het indexeren, zodat we de search queries naar Elasticsearch betrekkelijk eenvoudig kunnen houden.
Een willekeurige greep:
- Het
roman_number_filter
maakt van Romeinse cijfers (I, IX, XII) de gangbare decimale getallen (1, 9, 12). Daardoor kan je bij Walter zoeken op “Dorpstraat 23-III” en vinden we de “Dorpstraat 23-3” voor je; - Het
number_unit_filter
splitst huisnummers en toevoegingen en zorgt dat ze altijd in eenzelfde formaat worden geïndexeerd. Hierdoor kan je zoeken op “Dorpstraat 23 III” en vinden wij “Dorpstraat 23-3” voor je; - Het
dash_filter
haalt liggende streepjes uit adressen en vervangt ze door een spatie. Dat maakt het makkelijker om adressen te vinden die streepjes bevatten, zonder dat jij eraan hoeft te denken om die streepjes op de juiste plek te tikken;
Tenslotte splitsen we zelf het adres op in een aantal combinaties en slaan we een geolocatie op bij het adres. Hiermee kunnen we makkelijker adressen vinden binnen een bepaald gebied in onze infrastructuur.

Het indexeren van de BAG in Elasticsearch duurt op deze manier een uur. Zodra dat klaar is hebben we krap 11 GB aan data die we binnen milliseconden kunnen doorzoeken.
Doorzoekbaar maken
Nu we alle adressen uit de BAG geïndexeerd hebben, kunnen we zoekopdrachten op ons Elasticsearch-cluster gaan afvuren.
Tijdens het zoeken proberen we een zo goed mogelijke query voor Elasticsearch op te stellen. Als we geen cijfers in je input vinden, heeft het geen zin om een query te doen die het huisnummer een boost geeft. En als we een postcode aantreffen, kunnen we daar juist een flinke boost aan geven om alleen adressen in die postcode te vinden.
Uiteindelijk bestaat onze query uit een bool
query met een aantal must
en should
clauses daarin, met match
op één of meer van de velden die we tijdens het indexeren hebben gedefinieerd en opgeslagen.
Daarna maken we eenheidsworst van de BAG.
Converteer, indexeer, importeer, zoek, repeat
Een goede inrichting van onze data helpt ons met het doorzoeken van alle 9.152.803 adressen in Nederland met zo min mogelijk latency. We doen dit door alle beschikbare data met NLExtract-tools klaar te maken, zodat ze zo snel mogelijk geanalyseerd kunnen worden. Dankzij het gebruik van een aantal filters maken we daarna eenheidsworst van de BAG, een database die niet gemaakt is om snel doorzocht te worden.
De BAG is maar één van de grote datasets die we importeren. We gebruiken data van tientallen bronnen om waardevolle inzichten te kunnen geven over een huis. Maar daar de volgende keer meer over.

Buying a home?
Book your free orientation call with a Walter advisor. We will take you through the process of buying your next home.
Book a call — it's freeAchter de schermen



Walter Living is registered in The Netherlands with the address Walter Tech, B.V. Singel 542, 1017AZ, Amsterdam. Our Chamber of Commerce number is 73708585 and our tax ID is NL859636033B01.
Service
Would you rather contact us via WhatsApp? Send an app to +31 85 080 6860