WordPress 搜索页支持搜索自定义字段的方法

 7个月前     946  

文章目录

自定义字段是WordPress中非常强大的功能之一,在通过使用自定义帖子类型来扩展WordPress时,这个功能特别有用。我在开发OneNav主题时,创建了很多自定义字段,为帖子添加细节,比如收藏网址的Url地址,App的版本,书籍的刊号等等。不幸的是,WordPress 搜索页不能搜索出自定义字段的内容。为了解决这个问题,需要修改WordPress的搜索查询以包括自定义字段。

这里我贴出俩种方法共大家选择,分别为LEFT JOINEXISTS

LEFT JOIN 方法

此方法分为三步

1、Left Join

默认情况下,WordPress 搜索功能设置为仅搜索posts表,为了在我们的搜索中包含自定义字段数据,我们首先需要对数据库中的postmeta表执行左连接。

2、修改查询条件

修改 WordPress 的搜索查询包含自定义字段。

3、防止重复

此方法查询出的数据会产生重复项,我们需要在 SQL 查询中添加 DISTINCT 关键字,以防止返回重复项。

完整代码如下:

/**
 * WordPress 搜索页支持搜索自定义字段的方法
 * 原文地址:https://www.iowen.cn/wordpress-search-page-supports-custom-fields/
 *
 * 修改搜索查询的sql代码,将postmeta表左链接进去。
 */
function io_search_join( $join, $query ) {
    global $wpdb;
    if ( is_search() && $query->is_main_query() && !empty($query->query['s']) ) {
        $join .=' LEFT JOIN '. $wpdb->postmeta . ' AS post_metas ON ' . $wpdb->posts . '.ID = post_metas.post_id ';
    }
    return $join;
}
add_filter('posts_join', 'io_search_join',10,2 );

/**
 * 在wordpress查询代码中加入自定义字段值的查询。
 */
function io_search_where( $where, $query ) {
    global $pagenow, $wpdb;
    if ( is_search() && $query->is_main_query() && !empty($query->query['s']) ) {
        $meta_key = "'_sites_link','_spare_sites_link','_seo_desc','_sescribe','_down_list'"; //需搜索的自定义字段键名
        $where = preg_replace("/\(\s*".$wpdb->posts.".post_title\s+LIKE\s*(\'[^\']+\')\s*\)/","({$wpdb->posts}.post_title LIKE $1) OR ((post_metas.meta_value LIKE $1) AND (post_metas.meta_key IN ({$meta_key})))", $where ); 
    }
    return $where;
}
add_filter('posts_where', 'io_search_where',10,2);

/**
 * 在 SQL 查询中添加 DISTINCT 关键字,以防止返回重复项
 */
function io_search_distinct( $where, $query) {
    global $wpdb;
    if ( is_search() && $query->is_main_query() && !empty($query->query['s']) )  {
        return 'DISTINCT';
    }
    return $where;
}
add_filter( "posts_distinct", "io_search_distinct",10,2 );

EXISTS 方法

/**
 * WordPress 搜索页支持搜索自定义字段的方法
 * 原文地址:https://www.iowen.cn/wordpress-search-page-supports-custom-fields/
 *
 * EXISTS 方法查询自定义字段
 */
function io_posts_search_where($search, $query){
    global $wpdb; 
    if (is_search() && $query->is_main_query() && !empty($query->query['s'])) {
        $meta_key = "'_sites_link','_spare_sites_link','_seo_desc','_sescribe','_down_list'"; //需搜索的自定义字段键名
        $sql = " OR EXISTS (SELECT * FROM {$wpdb->postmeta} WHERE post_id={$wpdb->posts}.ID AND meta_key IN ({$meta_key}) AND meta_value like %s)"; 
        $like = '%' . $wpdb->esc_like($query->query['s']) . '%'; 
        $where = $wpdb->prepare($sql, $like);
        $search = preg_replace("/\(\s*".$wpdb->posts.".post_title\s+LIKE\s*(\'[^\']+\')\s*\)/","({$wpdb->posts}.post_title LIKE $1) {$where}", $search ); 
    } 
    return $search; 
}
add_action('posts_search', 'io_posts_search_where',10,2);

使用方法

使用方法很简单,还是万年不变的将上面俩种方法的任意一种代码添加到WordPress主题的“functions.php”文件中即可。

此代码不仅会修改前端的搜索,而且同时应用在了后端,你可以在后台文章列表搜索到自定义字段中包含搜索值的文章。

代码中$meta_key为需要查询的自定义字段,自定义字段非常多,把你想要检索到的字段添加到这个变量里面

区别&性能

如果你就几百篇文章,上面方法随便选;如果文章很多,根据我在一个 postmeta 表7w数据和 posts 表6k数据的数据库中测试,EXISTS 方法比 LEFT JOIN 基本上快一半的时间,数据库知识薄弱,如果有啥不对的地方,欢迎指正。

 

版权声明:一为 发表于 7个月前,共 2679 字。
转载请注明:WordPress 搜索页支持搜索自定义字段的方法 | 一为忆

暂无评论

暂无评论...