Adresssuche in PostgreSQL

Mar 12, 2022

development

Adresssuche in PostgreSQL

Ein interessantes Thema – vorallem, weil die Schreibweisen von Adressen oft nicht trivial sind. Auf die Schnelle habe ich folgende zwei Strategien gefunden:

  • pg_trgm: Dieses Modul erlaubt es, die Ähnlichkeit von Wörtern zu messen. Durch das Anlegen eines Index, ist diese Methode extrem performant.
  • Phonet: Erlaubt einen String auf einen „Aussprache“ String zu projizieren. Ähnlich klingende Strings mappen somit auf den gleichen String. Anschließend Abgleich mit pg_gtrm. Der Vorteil: Aussprachefehler werden „ausgebessert“ und führen zu einem besseren Match.

Wann funktioniert das gut? Wenn man die Menge an Möglichkeiten voreinschränkt. Dazu bietet sich natürlich die Postleitzahl an. In Österreich 4-stellig – aber es reicht, wenn man auch nur 1-2 Stellen eingibt. Vorangestellt oder nicht – je nach dem. Ich war mit dem Ergebnis sehr zufrieden.

Die Daten habe ich von http://www.statistik.at/verzeichnis/strassenliste/gemplzstr.zip bezogen, habe später aber eine bessere Datenquelle inkl. Hausnummern gefunden: https://www.bev.gv.at/portal/page?_pageid=713,2601271&_dad=portal&_schema=PORTAL

Die größte Herausforderung ist es sicher, die Adresse zu „zerlegen“. Beispiele sind:

Beliebige-Muster-Straße 7 1230 Wien

Bzw. mit Stiege und Block:

Beliebige-Muster-Straße 7/ 4 1230 Wien

Beliebige-Muster-Straße 7/B/3/4 1230 Wien

Mit regulären Ausdrücken prinzipiell möglich – nur kann man bei „named capture groups“ den Hausnummer / Block / Stiege / Türnummer teil nicht mehr zerlegen (ist denk, da nicht mehr context-free). Das Thema Hausnummer / Block / Stiege / Türnummer ist natürlich sehr interessant. Ich würde mir die Fragen stellen: PostgreSQL hat keine SPARSE Columns – Impact da Block und Stiege oft leer ist? Eventuell eine Tabelle mit „Häuser“ mit Spalte Hausnummer und JSOB für den „Rest“? Der „Rest“ muss ja nicht durchsucht werden?

Das Schema für die Straßennamen gestaltet sich relativ einfach (Tabellenstruktur wurde stur übernommen):

Die Suche nach Adressen habe ich mit Dappr und einer .NET Core Consolen Applikation getestet:

Ergebnis:

Man sieht, dass bei Rechtschreib- bzw. Aussprachefehler die Phonet Lösung etwas besser ist – allerdings auch nicht in dem Umfang, dass man sich jetzt eine zusätzliche Library ins Projekt holen muss.

Phonet findet man hier:

Zu erwähnen ist noch, das pg_trgm den Wortanfang höher gewichtet: