Ik heb een vraagje. Ik heb een tabel in de database met restaurants waarbij de postcode opgeslagen staat.
Nu wil ik dat gebruikers kunnen zoeken op postcode naar deze restaurants aan de hand van postcode. Maar niet alleen de postcode, maar ook omliggende, dus stel iemand zoekt op 1528 dan moeten ook de omliggende eruit komen, wellicht een straal nodig? Denk aan zoiets als thuisbezorgd zoeken.
Ik heb gedacht aan het getal plus en min doen maar dit geeft niet overal het gewenste resultaat uiteraard.
Is hier een API voor of iets wat ik kan gebruiken?
Misschien Google API, maar hoe zou ik dit dan moeten laten werken.
Hey, dankjewel deze had ik niet gevonden! Dat delimiter gedeelte ken ik eigenlijk niet. De lat/long kan ik waarschijnlijk wel bepalen met een google api call. Die functie dat je de afstanden kan bepalen is wel slim als ik de delimiter begrijp.
Oeps, had een reactie aan het oude topic toegevoegd.
Wat je in wezen doet is de set van coordinaten waar je complexe berekeningen op uitvoert van tevoren zoveel mogelijk inperken zodat je alleen op de echte interessante informatie deze berekeningen uitvoert. Dit levert waarschijnlijk veel performancewinst op.
Oeps, had een reactie aan het oude topic toegevoegd.
Wat je in wezen doet is de set van coordinaten waar je complexe berekeningen op uitvoert van tevoren zoveel mogelijk inperken zodat je alleen op de echte interessante informatie deze berekeningen uitvoert. Dit levert waarschijnlijk veel performancewinst op.
Het mag ook een vierkant zijn, dat is in principe geen probleem. Zoals thuisbezorgd of marktplaats moet het zijn dat je aan de hand van een postcode moet kunnen zoeken en resultaten krijgt met ook omliggende postcodes. Dus ik moet dus elke zoekopdracht postcode moet omzetten naar lat/long en dan ingevoerde lat/longs daarmee vergelijken. Is dit ook hoe ze dit bij zulke grotere sites aanpakken?
Het mag ook een vierkant zijn, dat is in principe geen probleem.
Daar gaat het niet om, het gaat om de efficiëntie en schaalbaarheid van jouw query.
Je moet het als volgt zien. Stel je hebt nu 100 filialen in jouw database staan. Vervolgens heb je een postcode die je omzet naar lat/lon (dit zou je trouwens ook kunnen bijhouden in je database zodat je dat niet elke keer opnieuw hoeft te bepalen) en sla je aan het rekenen. Voor al die 100 filialen moet een complexe rekensom worden uitgevoerd om te bepalen of er aan die conditie wordt voldaan en dus of dit in de resultaten moet worden opgenomen.
Stel dat er straks 10.000 filialen in jouw database zitten. Dan moet die berekening 10.000 keer worden uitgevoerd. Maar wat als je een extra conditie hebt die eerst het zoekgebied flink kleiner maakt, alsof je met een schaar een vierkantje knipt uit een hele grote kaart, op dat vierkantje staan misschien in zijn totaliteit maar 50 filialen. Alleen deze filialen worden vervolgens onderworpen aan de complexe rekensom, want de rest was al afgevallen omdat deze niet binnen het vierkantje vielen. Door deze voorselectie houd je de query schaalbaar.
En dan nog iets anders: het is niet per se erg dat er soms grote, langzame (en dit is iets anders dan "trage") queries worden uitgevoerd. Maar als dit onderdeel van zoekfunctionaliteit is (waar zit het meest nabijgelegen filiaal), dan zal zo'n query relatief vaak worden uitgevoerd. En het resultaat zal ook snel teruggeserveerd moeten worden want hier zitten mensen op te wachten. Je moet dus ook nadenken over de frequentie van aanroep en eventuele tijdsconstraints (maakt het uit dat de query lang duurt?), dit bepaalt tezamen mede het ontwerp van je queries en ook je database. Stel dat er 50 mensen tegelijkertijd aan het zoeken zijn en de database zit dan te stampen op de berekening van afstanden van 10.000 filialen? Dit heeft al snel een merkbaar sneeuwbaleffect.
Michel Hamelink op 09/04/2020 10:55:18
Is dit ook hoe ze dit bij zulke grotere sites aanpakken?
Waarschijnlijk zullen zij iets soortgelijks gebruiken want uiteindelijk komt dit alles neer op afstanden berekenen in een of andere vorm.
Je zou de spatial data types van MySQL kunnen gebruiken, want dan kun je de dichtstbijzijnde points vinden met een spatial join.
Alleen lost dat een belangrijkere complicatie niet op: de reisafstand tussen twee geografische punten is vaak heel anders dan je hemelsbreed meet met een rechte lijn. Bijvoorbeeld omdat er een rivier tussen ligt en de dichtstbijzijnde brug 20 km omrijden is. Dat los je alleen op met een API zoals de Distance Matrix API van het Google Maps Platform.
[quote="Michel Hamelink op 09/04/2020 10:55:18"]Het mag ook een vierkant zijn, dat is in principe geen probleem.
Daar gaat het niet om, het gaat om de efficiëntie en schaalbaarheid van jouw query.
Je moet het als volgt zien. Stel je hebt nu 100 filialen in jouw database staan. Vervolgens heb je een postcode die je omzet naar lat/lon (dit zou je trouwens ook kunnen bijhouden in je database zodat je dat niet elke keer opnieuw hoeft te bepalen) en sla je aan het rekenen. Voor al die 100 filialen moet een complexe rekensom worden uitgevoerd om te bepalen of er aan die conditie wordt voldaan en dus of dit in de resultaten moet worden opgenomen.
Stel dat er straks 10.000 filialen in jouw database zitten. Dan moet die berekening 10.000 keer worden uitgevoerd. Maar wat als je een extra conditie hebt die eerst het zoekgebied flink kleiner maakt, alsof je met een schaar een vierkantje knipt uit een hele grote kaart, op dat vierkantje staan misschien in zijn totaliteit maar 50 filialen. Alleen deze filialen worden vervolgens onderworpen aan de complexe rekensom, want de rest was al afgevallen omdat deze niet binnen het vierkantje vielen. Door deze voorselectie houd je de query schaalbaar.
En dan nog iets anders: het is niet per se erg dat er soms grote, langzame (en dit is iets anders dan "trage") queries worden uitgevoerd. Maar als dit onderdeel van zoekfunctionaliteit is (waar zit het meest nabijgelegen filiaal), dan zal zo'n query relatief vaak worden uitgevoerd. En het resultaat zal ook snel teruggeserveerd moeten worden want hier zitten mensen op te wachten. Je moet dus ook nadenken over de frequentie van aanroep en eventuele tijdsconstraints (maakt het uit dat de query lang duurt?), dit bepaalt tezamen mede het ontwerp van je queries en ook je database. Stel dat er 50 mensen tegelijkertijd aan het zoeken zijn en de database zit dan te stampen op de berekening van afstanden van 10.000 filialen? Dit heeft al snel een merkbaar sneeuwbaleffect.
Michel Hamelink op 09/04/2020 10:55:18
Is dit ook hoe ze dit bij zulke grotere sites aanpakken?
Waarschijnlijk zullen zij iets soortgelijks gebruiken want uiteindelijk komt dit alles neer op afstanden berekenen in een of andere vorm.
[/quote]
Oke dan begin ik het te begrijpen, nog best complex. Er is niet gevraagd om een kaart mogelijkheid. Dat lat long opslaan van bepaalde postcodes in de database is een slimme, scheelt api calls en snelheid. Hoe kan ik een query opzetten die flink kleiner is.
Is het rendabel om via het opgezochte adres de lat/long te krijgen (geo van google) en dan doormiddel van een eerder genoemde berekening die afstand te meten tussen de ingevoerde filialen (die ook lat/long hebben). Dan nog steeds misschien het zoekgebied kleiner maken, nog geen idee hoe ik dat dan wil aanpakken.
Is het rendabel om via het opgezochte adres de lat/long te krijgen (geo van google) en dan doormiddel van een eerder genoemde berekening die afstand te meten tussen de ingevoerde filialen (die ook lat/long hebben).
Die vraag beantwoordt je al min of meer zelf als je je bedient van postcodes:
Michel Hamelink op 10/04/2020 13:09:04
Dat lat long opslaan van bepaalde postcodes in de database is een slimme, scheelt api calls en snelheid.
Michel Hamelink op 10/04/2020 13:09:04
Hoe kan ik een query opzetten die flink kleiner is.
Weet niet precies wat je hiermee bedoelt, maar je kunt dit vraagstuk opdelen in delen. Je hebt het stuk waar je postcodes (eenmalig) omzet naar lat/lon, je hebt het stuk waarbij je (in PHP) een vierkant om de straal heenzet waarbij je twee coordinatenparen berekent en je hebt het stuk waarbij je daadwerkelijk afstanden berekent, en daarvoor heb je al een lap SQL. Het "enige" wat je nog moet doen is deze alle combineren.
Michel Hamelink op 10/04/2020 13:09:04
Dan nog steeds misschien het zoekgebied kleiner maken, nog geen idee hoe ik dat dan wil aanpakken.
Zoals eerder aangegeven is hier (gegeven een lat/lon coordinaat en een afstand in een bepaalde richting, bereken op grond hiervan een nieuw lat/lon paar) code voor te vinden, misschien heb ik deze zelf nog, ik zal hier eens naar zoeken.
Dit doe je dus op grond van het middelpunt van de cirkel (de postcode die je opgeeft). De linker bovenhoek van het omvattende vierkant is (middelPuntY - straalY, middelPuntX - straalX) en de rechter onderhoek is (middelPuntY + straalY, middelPuntX + straalX), waarbij straalX en straalY de berekende lat/lon verschillen zijn. Zoals in de andere thread aangegeven doe je met behulp van deze coordinaten een voorselectie op de filiaalkandidaten. Vervolgens inspecteer je enkel de filialen die binnen het vierkant en binnen de gewenste straal vallen.
En zoals @Ward terecht aangaf, er is waarschijnlijk nog steeds een verschil tussen de hemelsbrede afstand en afgelegde weg van begin- naar eindpunt.
Je zou ook kunnen kijken of het voorstel van @Ward meer soelaas biedt. Aangezien het een apart datatype betreft is dit waarschijnlijk vrij ver uitgeoptimaliseerd. Je zou ook beide kunnen uitproberen, en dan kijken welke sneller is.