Mysql
 sql >> Datenbank >  >> RDS >> Mysql

MYSQL Geo Search mit Distanzleistung

Der schnellste Weg, dies zu tun, ist die Verwendung der geospatialen Erweiterungen für MySQL, was einfach genug sein sollte, da Sie bereits eine MyISAM-Tabelle verwenden. Die Dokumentation für diese Erweiterungen finden Sie hier:http:/ /dev.mysql.com/doc/refman/5.6/en/spatial-extensions.html

Fügen Sie eine neue Spalte mit einem POINT-Datentyp hinzu:

ALTER TABLE `adverts` 
ADD COLUMN `geopoint` POINT NOT NULL AFTER `longitude`
ADD SPATIAL KEY `geopoint` (`geopoint`)

Sie können diese Spalte dann aus Ihren vorhandenen Breiten- und Längengradfeldern ausfüllen:

UPDATE `adverts` 
SET `geopoint` = GeomFromText(CONCAT('POINT(',`latitude`,' ',`longitude`,')'));

Der nächste Schritt ist das Erstellen eines Begrenzungsrahmens basierend auf dem eingegebenen Breiten- und Längengrad, der in Ihrem WHERE verwendet wird -Klausel als CONTAINS Zwang. Sie müssen einen Satz von X,Y POINT bestimmen Koordinaten, die für Ihre Anforderungen funktionieren, basierend auf dem gewünschten Suchgebiet und dem angegebenen Startpunkt.

Ihre letzte Abfrage sucht nach allen POINT Daten, die sich in Ihrer Suche POLYGON befinden , und Sie können dann eine Entfernungsberechnung verwenden, um Ihre Daten weiter zu verfeinern und zu sortieren:

SELECT a.*, 
    ROUND( SQRT( ( ( (adverts.latitude - '53.410778') * (adverts.latitude - '53.410778') ) * 69.1 * 69.1 ) + ( (adverts.longitude - '-2.97784') * (adverts.longitude - '-2.97784') * 53 * 53 ) ), 1 ) AS distance
FROM adverts a
WHERE a.type_id = 3
AND CONTAINS(a.geopoint, GeomFromText('Polygon((0 0,0 3,3 3,3 0,0 0))'))
HAVING distance < 25
ORDER BY distance DESC
LIMIT 0, 30

Beachten Sie, dass GeomFromText('Polygon((0 0,0 3,3 3,3 0,0 0))') oben wird nicht funktionieren , müssen Sie die Koordinaten durch gültige Punkte um Ihren Suchstart herum ersetzen. Wenn Sie erwarten, dass sich der Breitengrad/Längengrad ändert, sollten Sie einen Trigger verwenden, um den POINT beizubehalten Daten und dem zugehörigen SPATIAL KEY auf dem Laufenden. Bei großen Datensätzen sollten Sie eine erheblich verbesserte Leistung gegenüber der Berechnung einer Entfernung für jeden Datensatz und der Filterung mit einem HAVING sehen Klausel. Ich persönlich habe Funktionen zur Bestimmung der Entfernung und zur Erstellung des umgrenzenden POLYGON definiert .