Поиск близости

Как приложение выполняет поиск по близости? Например, пользователь вводит почтовый код, затем приложение перечисляет все предприятия в пределах 20 миль, заказанных по близости.

Я хочу построить что-то подобное в PHP и MySQL. Правильно ли этот подход?

  1. Получите адреса для местоположений, которые меня интересуют и хранят в моей базе данных
  2. Геокодировать все адреса с помощью службы геокодирования Google
  3. Напишите запрос базы данных, который включает формулу Хаверсина, чтобы выполнить поиск близости и упорядочение

Это нормально? На шаге 3 я собираюсь рассчитать близость для каждого запроса. Лучше ли иметь таблицу PROXIMITY, в которой указано расстояние между каждым бизнесом и несколькими ссылочными позициями?

Solutions Collecting From Web of "Поиск близости"

Если есть достаточное количество записей для скорости, это способ их индексации раньше времени.

Определите сетку бункеров около 20 миль на боку. Сохраните номер ячейки с записью каждого магазина. Во время поиска вычислите числа всех бинов, которые пересекают 20-мильный радиус от точки поиска. Затем загрузите все магазины в любом из этих ящиков и действуйте по-прежнему.

Мы используем это, чтобы сделать много тысяч очков. Важно, если вы выполняете это в SQL, чтобы иметь индекс в столбце Широта и долгота. Мы попытались сделать это в SQL 2008 с пространственными индексами, но мы действительно не видели увеличения производительности, которого мы ожидали. Хотя, если вы хотите рассчитать на определенном расстоянии от ZIP, вам нужно подумать о том, собираетесь ли вы использовать ZIP-центр или многоугольное представление почтового индекса.

Haversine forumla – хорошее место для начала.

У нас не было проблем с производительностью, вычисляющих расстояние «на лету», мы заранее рассчитываем его для некоторых приложений, где мы знаем моменты раньше времени, и будут миллионы записей.

SELECT [DistanceRadius]= 69.09 * DEGREES( ACOS( SIN( RADIANS(latitude) )*SIN( RADIANS(@ziplat) ) + COS( RADIANS(latitude) )*COS( RADIANS(@ziplat) ) * COS( RADIANS(longitude - (@ziplon)) ) ) ) ,* FROM table ) sub WHERE sub.DistanceRadius < @radius 

Мы делаем это примерно в 1200 местах. Я бы просто использовал формулу Хаверсина «на лету», хотя в зависимости от вашего приложения лучше было бы хранить его в PHP вместо SQL. (Наша реализация в .net, поэтому ваше перемещение может меняться).

На самом деле наш самый большой недостаток в том, как мы его реализовали, заключается в том, что каждый расчет (до недавнего времени) должен был быть рассчитан на уровне данных, который был болезненно медленным (когда я говорю «медленно», я действительно имею в виду немедленное, это заняло секунду или около того ), но это было связано с тем, что он должен был рассчитать расстояние для всех 1200 мест на основе поставленного почтового индекса.

В зависимости от выбранного вами маршрута существуют способы ускорения вычислений расстояния расстояния, просмотра долготы и широты и удаления тех, которые находятся за пределами заданного диапазона (например, если вы просматриваете весь адрес в пределах 20 миль, долготу, вы можете рассчитать, что все адреса должны находиться в 20 милях.) Это может ускорить ваш запрос, если это необходимо.

Мы действительно посмотрели на сохранение всех возможных комбинаций в нашей базе данных. На самом деле это звучит так, будто это может быть большой магазин данных, но это действительно не в большом объеме вещей. С индексами это может быть довольно быстро, и вам не нужно беспокоиться об оптимизации алгоритмов и т. Д. Мы решили против этого, потому что у нас было уравнение в C #, и это позволило нам кэшировать информацию, необходимую для выполнения всех вычислений в бизнес-уровня. Либо все будет работать отлично, это всего лишь вопрос ваших предпочтений.