Я использую сторонний сервис для заполнения постов на моем сайте WordPress. Большая часть информации, поступающей из сервиса, хранится в виде свойств поста WordPress (заголовок, контент, изображения и т. Д. c), но часть из них хранится в виде метаданных поста (уникальные идентификаторы сервиса для каждого поста и другие метаданные). Служба предлагает поиск по радиусу, чтобы найти сообщения, которые соответствуют определенному местоположению, и возвращает идентификаторы для соответствующих сообщений. Моя цель состоит в том, чтобы взять эти идентификаторы и вернуть постраничный набор результатов из сообщений WP, чтобы все форматировалось, как любая другая страница поиска на сайте WP. У меня есть рабочая реализация этого, но она очень медленная, и я ищу совет о том, как ее ускорить, или о различных подходах к достижению sh моей цели.
Моя текущая реализация делает нумерацию страниц oop для всех соответствующих сообщений в сервисе (это может вернуть 10 результатов или 1000 результатов). Затем я беру идентификаторы из этого набора результатов и передаю их в запрос WP, чтобы ограничить запрос мета-значением идентификаторов. Запрос становится медленнее, чем больше набор данных из сервиса. Я делаю это таким образом, чтобы позволить мне использовать нумерацию страниц WP. Если бы я просто вернул одну страницу в разбивке по страницам, WordPress не знал бы, что было бы больше результатов для разбивки на страницы. Буду очень признателен за любые советы или рекомендации о том, как сделать этот процесс более производительным.
Вот код, который у меня есть до сих пор. В настоящее время он работает, но, как уже упоминалось, чем больше набор данных из службы, тем больше времени занимает запрос:
<?php
class Search {
const SEARCH_PREFIX = 'test';
protected static $api_params_whitelist = [
'search',
'near_zip',
'near_city',
'radius',
'featured_only',
'currently_listed_only',
'registrable_only',
'page',
'per_page',
'sort'
];
public static function radius_search($query) {
$field_prefix = Search::SEARCH_PREFIX;
$search = $query->get($field_prefix . 'term');
$location = $query->get($field_prefix . 'location');
$radius = $query->get($field_prefix . 'radius');
if (
$query->is_main_query()
&& (strlen($location) > 0)
) {
// Lookup result IDs for radius.
if ($resultIds = self::get_result_ids($search, $location, $radius)) {
$query->set( 'meta_query', array(
// Search for the result id stored in `post_meta`.
array(
'key' => 'id',
'value' => $resultIds,
'compare' => 'IN',
),
) );
} else {
// Force no results
$query->set( 'post__in', array(0) );
}
} elseif ( strlen( $search ) > 0 ) {
// Fallback to standard WP search w/o radius search
$query->set( 's', $search );
}
}
public static function add_query_vars_filter( $vars ) {
$field_prefix = Search::SEARCH_PREFIX;
$query_variables = [
$field_prefix . 'term',
$field_prefix . 'location',
$field_prefix . 'radius'
];
foreach ($query_variables as $var) {
$vars[] = $var;
}
return $vars;
}
private static function get_api_handler() {
$credentials = Synchronize::get_credentials();
if( !isset( $credentials['subdomain'] ) ) {
return false;
}
$api = new \My_Api( $credentials['subdomain'] );
$api->setTimeoutInSeconds( 10 );
return $api;
}
private static function get_result_ids($search, $location, $radius) {
$api = self::get_api_handler();
$page = 1;
$per_page = 60;
$results = [];
$params = $_GET;
$params['per_page'] = $per_page;
$query_params = $api->getQueryParams( $params, Search::SEARCH_PREFIX, self::$api_params_whitelist );
do {
$query_params['page'] = $page;
$query_params['fields'] = [
'id'
];
$results = $api->get( '/search', $query_params );
$resultCount = count($results);
if ($results && $resultCount > 0) {
$results = array_merge($results, $results);
}
$page++;
} while ($results && $resultCount > 0);
if (count($results)) {
return array_column($results, 'id');
}
return false;
}
}