WordPress搜索结果按浏览量排序的实现方法

本文介绍了在WordPress中实现搜索结果按浏览量排序的两种方法。方案一通过插件组合实现,无需代码,推荐使用Post Views Counter和Relevanssi插件配合设置。方案二为纯代码实现,通过修改主题的functions.php文件,利用WP-PostViews插件的数据进行自定义排序,并提供前端排序选项。

WordPress基础教程
阅读时间: 151 分钟
最后更新时间:2026年2月17日

在WordPress中实现搜索结果按浏览量排序,需要结合浏览量统计功能。以下是几种实现方法,从简单到复杂:

方案一:使用插件组合(无需代码,最简单)

1. 安装必需插件

  • WP-PostViews​ 或 Post Views Counter​ – 用于统计浏览量
  • SearchWP​ 或 Relevanssi​ – 高级搜索插件(支持自定义排序)

2. 使用 Post Views Counter + Relevanssi(推荐组合)

  1. 安装并激活 Post Views Counter​ 和 Relevanssi
  2. 在 Relevanssi 设置中:
    • 进入“设置” > “Relevanssi” > “搜索结果排序”
    • 选择“自定义字段”作为主要排序
    • 在字段中输入:post_views(Post Views Counter 使用的字段名)
    • 选择“数字”和“降序”

方案二:纯代码实现(使用 WP-PostViews 插件的数据)

如果你已经在使用 WP-PostViews 插件,添加以下代码到主题的 functions.php

/**
 * 修改搜索结果查询,按浏览量排序
 */
function search_results_by_views( $query ) {
    // 仅在前端搜索结果页面,且是主查询
    if ( ! is_admin() && $query->is_main_query() && $query->is_search() ) {
        // 获取排序参数
        $orderby = isset( $_GET['orderby'] ) ? $_GET['orderby'] : 'views';
        
        if ( $orderby === 'views' ) {
            $query->set( 'meta_key', 'views' ); // WP-PostViews 的字段名
            $query->set( 'orderby', 'meta_value_num' );
            $query->set( 'order', 'DESC' );
        }
    }
}
add_action( 'pre_get_posts', 'search_results_by_views' );

/**
 * 在搜索结果页面添加排序选项
 */
function add_search_sorting_options() {
    if ( is_search() ) {
        $current_order = isset( $_GET['orderby'] ) ? $_GET['orderby'] : 'relevance';
        $search_query = get_search_query();
        ?>
        <div class="search-sorting-options">
            <span>排序方式:</span>
            <a href="<?php echo esc_url( add_query_arg( array( 's' => $search_query, 'orderby' => 'relevance' ) ) ); ?>" 
               class="<?php echo $current_order === 'relevance' ? 'active' : ''; ?>">
                相关度
            </a>
            <a href="<?php echo esc_url( add_query_arg( array( 's' => $search_query, 'orderby' => 'views' ) ) ); ?>" 
               class="<?php echo $current_order === 'views' ? 'active' : ''; ?>">
                浏览量
            </a>
            <a href="<?php echo esc_url( add_query_arg( array( 's' => $search_query, 'orderby' => 'date' ) ) ); ?>" 
               class="<?php echo $current_order === 'date' ? 'active' : ''; ?>">
                最新
            </a>
        </div>
        
        <style>
            .search-sorting-options {
                margin: 20px 0;
                padding: 15px;
                background: #f5f5f5;
                border-radius: 5px;
            }
            .search-sorting-options span {
                font-weight: bold;
                margin-right: 10px;
            }
            .search-sorting-options a {
                margin: 0 10px;
                padding: 5px 15px;
                background: #fff;
                border: 1px solid #ddd;
                border-radius: 3px;
                text-decoration: none;
                color: #333;
            }
            .search-sorting-options a:hover,
            .search-sorting-options a.active {
                background: #0073aa;
                color: white;
                border-color: #0073aa;
            }
        </style>
        <?php
    }
}
add_action( 'before_search_results', 'add_search_sorting_options' );
// 如果主题没有这个hook,可以在search.php模板中添加:do_action('before_search_results');

方案三:不使用插件,完全自定义浏览量统计 + 排序

步骤1:添加浏览量统计功能

/**
 * 记录文章浏览量(不依赖插件)
 */
function track_post_views( $post_id ) {
    if ( ! is_single() ) return;
    
    if ( empty( $post_id ) ) {
        global $post;
        $post_id = $post->ID;
    }
    
    $count_key = 'post_views_count';
    $count = get_post_meta( $post_id, $count_key, true );
    
    if ( $count == '' ) {
        $count = 0;
        delete_post_meta( $post_id, $count_key );
        add_post_meta( $post_id, $count_key, '1' );
    } else {
        $count++;
        update_post_meta( $post_id, $count_key, $count );
    }
}
// 移除这个动作钩子,如果你不希望在预览时统计
remove_action( 'wp_head', 'adjacent_posts_rel_link_wp_head', 10, 0 );

// 在single.php中调用
function get_post_views( $post_id ) {
    $count_key = 'post_views_count';
    $count = get_post_meta( $post_id, $count_key, true );
    
    if ( $count == '' ) {
        delete_post_meta( $post_id, $count_key );
        add_post_meta( $post_id, $count_key, '0' );
        return 0;
    }
    
    return $count;
}

步骤2:在single.php模板中显示和统计

single.php的合适位置添加:

<?php
// 显示浏览量
echo '浏览:' . get_post_views( get_the_ID() );

// 统计浏览量(放在文章内容之后)
track_post_views( get_the_ID() );
?>

步骤3:修改搜索查询

/**
 * 搜索结果按自定义浏览量排序
 */
function custom_search_orderby_views( $query ) {
    if ( ! is_admin() && $query->is_main_query() && $query->is_search() ) {
        $order = isset( $_GET['order'] ) ? $_GET['order'] : 'view_desc';
        
        switch ( $order ) {
            case 'view_desc':
                $query->set( 'meta_key', 'post_views_count' );
                $query->set( 'orderby', 'meta_value_num' );
                $query->set( 'order', 'DESC' );
                break;
            case 'view_asc':
                $query->set( 'meta_key', 'post_views_count' );
                $query->set( 'orderby', 'meta_value_num' );
                $query->set( 'order', 'ASC' );
                break;
        }
    }
}
add_action( 'pre_get_posts', 'custom_search_orderby_views' );

方案四:高级实现 – 带AJAX的实时搜索排序

创建一个更高级的搜索排序系统:

/**
 * 增强版搜索排序系统
 */
class Advanced_Search_Sorter {
    
    public function __construct() {
        add_action( 'pre_get_posts', array( $this, 'modify_search_query' ) );
        add_action( 'wp_ajax_search_sort', array( $this, 'ajax_search_results' ) );
        add_action( 'wp_ajax_nopriv_search_sort', array( $this, 'ajax_search_results' ) );
        add_action( 'wp_enqueue_scripts', array( $this, 'enqueue_scripts' ) );
    }
    
    /**
     * 修改搜索结果查询
     */
    public function modify_search_query( $query ) {
        if ( ! is_admin() && $query->is_main_query() && $query->is_search() ) {
            $sort_by = get_query_var( 'sort_by', 'relevance' );
            
            if ( $sort_by === 'views_desc' ) {
                $query->set( 'meta_key', 'post_views_count' );
                $query->set( 'orderby', array( 
                    'meta_value_num' => 'DESC',
                    'date' => 'DESC'
                ) );
            } elseif ( $sort_by === 'views_asc' ) {
                $query->set( 'meta_key', 'post_views_count' );
                $query->set( 'orderby', array( 
                    'meta_value_num' => 'ASC',
                    'date' => 'DESC'
                ) );
            }
        }
    }
    
    /**
     * 添加排序参数到查询变量
     */
    public function add_query_vars( $vars ) {
        $vars[] = 'sort_by';
        return $vars;
    }
    
    /**
     * 注册脚本
     */
    public function enqueue_scripts() {
        if ( is_search() ) {
            wp_enqueue_script( 'search-sorter', get_template_directory_uri() . '/js/search-sorter.js', array( 'jquery' ), '1.0', true );
            wp_localize_script( 'search-sorter', 'searchSorter', array(
                'ajaxurl' => admin_url( 'admin-ajax.php' ),
                'nonce'   => wp_create_nonce( 'search_sort_nonce' )
            ) );
        }
    }
    
    /**
     * AJAX获取排序结果
     */
    public function ajax_search_results() {
        check_ajax_referer( 'search_sort_nonce', 'nonce' );
        
        $search_query = sanitize_text_field( $_POST['s'] );
        $sort_by = sanitize_text_field( $_POST['sort_by'] );
        $paged = intval( $_POST['paged'] ) ?: 1;
        
        $args = array(
            's'              => $search_query,
            'post_type'      => 'post',
            'posts_per_page' => 10,
            'paged'         => $paged,
            'post_status'   => 'publish'
        );
        
        // 设置排序
        switch ( $sort_by ) {
            case 'views_desc':
                $args['meta_key'] = 'post_views_count';
                $args['orderby'] = 'meta_value_num';
                $args['order'] = 'DESC';
                break;
            case 'date_desc':
                $args['orderby'] = 'date';
                $args['order'] = 'DESC';
                break;
            case 'relevance':
            default:
                // 使用默认相关性排序
                break;
        }
        
        $query = new WP_Query( $args );
        
        ob_start();
        
        if ( $query->have_posts() ) {
            while ( $query->have_posts() ) {
                $query->the_post();
                ?>
                <article class="search-result-item">
                    <h3><a href="<?php the_permalink(); ?>"><?php the_title(); ?></a></h3>
                    <div class="post-meta">
                        <span class="views">浏览:<?php echo get_post_views( get_the_ID() ); ?></span>
                        <span class="date"><?php echo get_the_date(); ?></span>
                    </div>
                    <div class="excerpt"><?php the_excerpt(); ?></div>
                </article>
                <?php
            }
            
            // 分页
            if ( $query->max_num_pages > 1 ) {
                echo '<div class="search-pagination">';
                echo paginate_links( array(
                    'base'    => add_query_arg( 'paged', '%#%' ),
                    'format'  => '',
                    'current' => $paged,
                    'total'   => $query->max_num_pages
                ) );
                echo '</div>';
            }
        } else {
            echo '<p>没有找到相关结果。</p>';
        }
        
        wp_reset_postdata();
        
        $output = ob_get_clean();
        wp_send_json_success( array( 'html' => $output ) );
    }
    
    /**
     * 显示排序控件
     */
    public static function display_sort_controls() {
        if ( ! is_search() ) return;
        
        $current_sort = get_query_var( 'sort_by', 'relevance' );
        $search_query = get_search_query();
        ?>
        <div class="search-sort-controls">
            <select id="search-sort-select" data-search="<?php echo esc_attr( $search_query ); ?>">
                <option value="relevance" <?php selected( $current_sort, 'relevance' ); ?>>
                    按相关度排序
                </option>
                <option value="views_desc" <?php selected( $current_sort, 'views_desc' ); ?>>
                    按浏览量(高→低)
                </option>
                <option value="date_desc" <?php selected( $current_sort, 'date_desc' ); ?>>
                    按时间(新→旧)
                </option>
            </select>
            
            <div class="sort-links">
                <a href="<?php echo esc_url( add_query_arg( 'sort_by', 'relevance' ) ); ?>" 
                   class="<?php echo $current_sort === 'relevance' ? 'active' : ''; ?>">
                    相关度
                </a>
                <a href="<?php echo esc_url( add_query_arg( 'sort_by', 'views_desc' ) ); ?>" 
                   class="<?php echo $current_sort === 'views_desc' ? 'active' : ''; ?>">
                    浏览量
                </a>
                <a href="<?php echo esc_url( add_query_arg( 'sort_by', 'date_desc' ) ); ?>" 
                   class="<?php echo $current_sort === 'date_desc' ? 'active' : ''; ?>">
                    最新
                </a>
            </div>
        </div>
        
        <style>
            .search-sort-controls {
                margin: 20px 0;
                padding: 20px;
                background: #f8f9fa;
                border-radius: 8px;
                display: flex;
                justify-content: space-between;
                align-items: center;
            }
            #search-sort-select {
                padding: 8px 15px;
                border: 2px solid #ddd;
                border-radius: 4px;
                font-size: 14px;
            }
            .sort-links a {
                margin-left: 15px;
                padding: 8px 20px;
                background: white;
                border: 2px solid #ddd;
                border-radius: 4px;
                text-decoration: none;
                color: #555;
                font-weight: 500;
            }
            .sort-links a:hover,
            .sort-links a.active {
                background: #0073aa;
                color: white;
                border-color: #0073aa;
            }
        </style>
        <?php
    }
}

// 初始化
new Advanced_Search_Sorter();
add_filter( 'query_vars', array( 'Advanced_Search_Sorter', 'add_query_vars' ) );
add_action( 'before_search_results', array( 'Advanced_Search_Sorter', 'display_sort_controls' ) );

对应的JavaScript文件 (search-sorter.js)

jQuery(document).ready(function($) {
    // 下拉选择排序
    $('#search-sort-select').on('change', function() {
        var sortBy = $(this).val();
        var searchQuery = $(this).data('search');
        
        $.ajax({
            url: searchSorter.ajaxurl,
            type: 'POST',
            data: {
                action: 'search_sort',
                nonce: searchSorter.nonce,
                s: searchQuery,
                sort_by: sortBy,
                paged: 1
            },
            beforeSend: function() {
                $('.search-results').html('<div class="loading">加载中...</div>');
            },
            success: function(response) {
                if (response.success) {
                    $('.search-results').html(response.data.html);
                    
                    // 更新URL(不刷新页面)
                    var newUrl = window.location.pathname + '?s=' + encodeURIComponent(searchQuery) + '&sort_by=' + sortBy;
                    window.history.pushState({path: newUrl}, '', newUrl);
                }
            }
        });
    });
    
    // 处理分页链接的AJAX
    $(document).on('click', '.search-pagination a', function(e) {
        e.preventDefault();
        
        var pageUrl = $(this).attr('href');
        var pageNum = getParameterByName('paged', pageUrl) || 1;
        var sortBy = getParameterByName('sort_by', window.location.href) || 'relevance';
        var searchQuery = getParameterByName('s', window.location.href);
        
        $.ajax({
            url: searchSorter.ajaxurl,
            type: 'POST',
            data: {
                action: 'search_sort',
                nonce: searchSorter.nonce,
                s: searchQuery,
                sort_by: sortBy,
                paged: pageNum
            },
            beforeSend: function() {
                $('.search-results').html('<div class="loading">加载中...</div>');
            },
            success: function(response) {
                if (response.success) {
                    $('.search-results').html(response.data.html);
                }
            }
        });
    });
    
    // 从URL获取参数
    function getParameterByName(name, url) {
        if (!url) url = window.location.href;
        name = name.replace(/[\[\]]/g, '\\$&');
        var regex = new RegExp('[?&]' + name + '(=([^&#]*)|&|#|$)'),
            results = regex.exec(url);
        if (!results) return null;
        if (!results[2]) return '';
        return decodeURIComponent(results[2].replace(/\+/g, ' '));
    }
});

使用建议

  1. 新手/快速上线:使用方案一(插件组合),最稳定
  2. 有一定开发能力:使用方案二,配合现有WP-PostViews插件
  3. 需要完全自定义:使用方案三,不依赖任何插件
  4. 需要最佳用户体验:使用方案四,支持AJAX无刷新排序

注意事项

  1. 性能考虑:浏览量大的站点,考虑使用缓存或定期更新排序索引
  2. SEO优化:为排序链接添加rel="nofollow",避免蜘蛛重复爬取
  3. 数据准确性:考虑排除机器人访问,确保浏览量数据真实
  4. 移动端适配:确保排序控件在移动设备上可用

这篇文章有用吗?

点击星号为它评分!

平均评分 5 / 5. 投票数: 1

到目前为止还没有投票!成为第一位评论此文章。

在AI里面继续讨论:

曾凤祥

曾凤祥

WordPress技术负责人
小兽WordPress凭借15年的WordPress企业网站开发经验,坚持以“为企业而生的WordPress服务”为宗旨,累计为10万多家客户提供高品质WordPress建站服务,得到了客户的一致好评。我们一直用心对待每一个客户,我们坚信:“善待客户,将会成为终身客户”。小兽WordPress能坚持多年,是因为我们一直诚信。

相关文章

如何让线上业务更上一层楼

还没有WordPress网站

还没有WordPress网站

不管你从事什么行业,WordPress都会为你提供一个专业的主题模板。在WordPress市场上有成千上万的免费主题,适合很多中小企业。

查看所有模板
已经有WordPress网站

已经有WordPress网站

小兽WordPress诚邀你一起学习WordPress,愿与各方携手升级改善您的WordPress网站,一起交流网站加速,网站优化等问题。

马上交个朋友
微信联系
chat 扫码联系
模板建站
挑选模板
网站定制
免费诊断
咨询热线
咨询热线

189-0733-7671

返回顶部