php - 使用第三方服务填充和搜索 WordPress 帖子
问题描述
我使用第三方服务将帖子填充到我的 WordPress 网站中。来自服务的大部分信息存储为 WordPress 帖子属性(标题、内容、图像等),但其中一些信息存储为帖子元数据(每个帖子和其他元数据的服务唯一标识符)。这些服务提供半径搜索以查找在给定位置内匹配的帖子,并返回匹配帖子的 ID。我的目标是获取这些 ID 并从 WP 帖子返回分页结果集,以便所有内容都像 WP 站点中的任何其他搜索页面一样格式化。我有一个可行的实现,但速度很慢,我正在寻找有关如何加快速度的建议,或者不同的方法来实现我的目标。
我当前的实现对服务上所有匹配的帖子进行了分页循环(这可能返回 10 个结果或 1000 个结果)。然后我从该结果集中获取 ID 并将它们传递到 WP Query 以通过 ID 的元值来限制请求。来自服务的数据集越大,请求就越慢。我这样做是为了让我能够利用 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;
}
}
解决方案
推荐阅读
- c++ - 为什么我不能用模板 push_back 一个对象?
- c# - 谷歌地图 url 使用和谷歌 api
- java - 初始化 VM 时出错,无法为对象堆保留足够的空间
- r - 为什么 predict.lm 返回 NA 作为 R 中的预测?
- groovy - 在使用 Groovy 验证 Katalon 上缺少元素后,如何捕获错误或使用“try and catch”
- http - 尝试使用 IFTTT 向物联网模块发送字符串
- javascript - 如何在python或java中复制JCryption1.1.js加密方法
- r - 在 ggplot r 中为两组女性创建直方图
- haskell - 在 raku 的模块中使用 Haskell 之类的 Prelude 模块
- python - 为什么每次打开 cmd 都需要激活 conda 和我的 venv?这是正常的吗?