Вопрос или проблема
Привет, я работаю над локатором магазинов.
У меня есть пользовательская запись “клиники”, где я сохраняю детали клиники (адрес, .., широта, долгота). Каждый раз, когда я публикую новую клинику, я также сохраняю post_id, широту и долготу в пользовательской таблице “lat_lng_post”.
Я могу искать клиники в пределах определенного расстояния, используя фильтр post_where следующим образом:
add_filter( 'posts_where' , 'location_posts_where' )
function location_posts_where( $where )
{
// $lat и $lng - это широта и долгота искомой точки
global $wpdb;
$where .= " AND $wpdb->posts.ID IN (SELECT post_id FROM lat_lng_post
WHERE
(6371 * acos( cos( radians(" . $lat . ") )
* cos( radians( lat ) )
* cos( radians( lng )
- radians(" . $lng . ") )
+ sin( radians(" . $lat . ") )
* sin( radians( lat ) ) ) ) <= 150
ORDER BY
( 6371 * acos( cos( radians(" . $lat . ") )
* cos( radians( lat ) )
* cos( radians( lng )
- radians(" . $lng . ") )
+ sin( radians(" . $lat . ") )
* sin( radians( lat ) ) ) ) ASC)";
return $where;
}
Я получаю клиники в пределах фиксированного расстояния (150 км), но они не упорядочены по расстоянию. Они показываются в порядке даты публикации.
Я попытался установить orderby на none:
$args = array (
'post_type' => 'clinica',
'orderby' => 'none'
);
Но это не сработало. Как я могу заставить упорядочить по тому правилу ORDER BY, которое я установил в запросе?
Используя WP_Query
, вы можете упорядочить результаты по meta_value_num
:
$args = array (
'post_type' => 'clinica',
'meta_key' => 'distance_field_name',
'orderby' => 'meta_value_num',
'order' => 'DESC'
);
Ответ или решение
Для решения проблемы сортировки результатов WP_Query по вычисленному полю расстояния между точками, необходимо внести некоторые изменения в вашу реализацию. Данный подход позволит вам получить список клиник, отсортированных по близости к определенной точке, используя параметры запроса и фильтры WordPress.
Введение
Вы хотите отображать клиники, которые находятся в определенном радиусе от заданной точки, и сортировать их по расстоянию. Ваша текущая реализация находит клиники, но сортировка осуществляется по дате публикации. Это можно исправить, добавив вычисляемое поле для расстояния в запрос.
Решение
Шаг 1: Расчет расстояния
Прежде всего, вы можете вычислить расстояние до каждой клиники в подзапросе, который будет присоединяться к основному запросу. Для этого вам нужно будет расширить ваш фильтр posts_where
так, чтобы возвращать не только подходящие клиники, но и расстояние до них.
Шаг 2: Использование posts_orderby
Добавьте следующий код в файл вашей темы или в плагин:
add_filter( 'posts_orderby', 'location_posts_orderby' );
function location_posts_orderby( $orderby ) {
global $wpdb;
// Добавляем вычисленное поле расстояния в оператор ORDER BY
$orderby = "( 6371 * acos( cos( radians(" . $lat . ") )
* cos( radians( lat ) )
* cos( radians( lng )
- radians(" . $lng . ") )
+ sin( radians(" . $lat . ") )
* sin( radians( lat ) ) ) ) ASC";
return $orderby;
}
Шаг 3: Изменение вашего основного запроса
Теперь вам нужно изменить ваш основной запрос, добавив правильные параметры для сортировки:
$args = array(
'post_type' => 'clinica',
'posts_per_page' => -1, // или любое другое количество
);
// Получите широту и долготу
$lat = /* Ваши координаты широты */;
$lng = /* Ваши координаты долготы */;
add_filter( 'posts_where', 'location_posts_where' );
add_filter( 'posts_orderby', 'location_posts_orderby' );
$query = new WP_Query( $args );
// не забудьте снять фильтры после использования
remove_filter( 'posts_where', 'location_posts_where' );
remove_filter( 'posts_orderby', 'location_posts_orderby' );
Шаг 4: Дополнительные меры
-
Оптимизация производительности: Убедитесь, что ваша база данных индексирована для повышения производительности запросов, связанных с геолокацией. Используйте методы кэширования для уменьшения нагрузки на сервер, особенно если у вас много клиник.
-
Использование мета-полей: Вместо вычисления расстояния в каждом запросе, вы также можете сохранять рассчитанное расстояние в мета-поле. Это может упростить ваши запросы, но потребует дополнительной логики для обновления этих значений в случае изменения местоположения клиники.
Заключение
С помощью вышеуказанных шагов вам удастся упорядочить результаты WP_Query на основе расстояния до заданной точки. Это значительно улучшит функциональность вашего магазина-локатора и принесет большую пользу пользователям, поскольку они смогут легче находить ближайшие клиники. Использование корректных фильтров и методов сортировки – ключ к созданию эффективного решения.