You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

WordPress中合并多个WP_Query搜索结果的问题求助

WordPress多文章类型搜索合并结果问题

我正在开发一个WordPress项目,需要跨多种文章类型和分类法执行搜索并展示合并后的结果。我已为每种文章类型和分类法创建了独立的WP_Query对象,获取各查询返回的文章ID并合并为单个数组,但在使用合并后的ID创建最终WP_Query对象时遇到问题,无法得到预期结果。

我尝试了以下代码,但没有返回任何结果:

function data_fetch() {
    check_ajax_referer('data_fetch_nonce', 'security');

    $keyword = isset($_POST['keyword']) ? sanitize_text_field($_POST['keyword']) : ''; 

    $page_query = new WP_Query(array(
        'fields' => 'ids',
        'posts_per_page' => -1,
        's' => $keyword,
        'post_type' => 'page',
        'post_status' => 'publish',
        'tax_query' => array(
            array(
                'taxonomy' => 'page_category',
                'field' => 'slug',
                'terms' => 'zabiegi',
            ),
        ),
    ));
    
    // Query for your custom post type
    $custom_post_type_query = new WP_Query(array(
        'fields' => 'ids',
        'posts_per_page' => -1,
        's' => $keyword,
        'post_type' => 'uslugi', // Replace with your custom post type slug
        'post_status' => 'publish',
    ));
    
    // Concatenate posts arrays
    $combined_posts = array_merge($page_query->posts, $custom_post_type_query->posts);
    
    // Create final query
    $combined_results = new WP_Query(array(
        'post__in' => $combined_posts,
    ));

    // Merge the results
    $combined_results = new WP_Query();

    if ($combined_results->have_posts()) {
        echo '<div class="search-results">';
        while ($combined_results->have_posts()) {
            $combined_results->the_post();
            echo '<div class="search-result-item">';
            echo '<div class="search-result-wrapper d-flex">';
            echo '<div class="result-content">';
            echo '<p class="result-title"><a class="p c-heading" href="' . esc_url(get_permalink()) . '">' . get_the_title() . '</a></p>';
            echo '</div>';
            echo '</div>';
            echo '<div class="result-action">';
            echo '<a class="result-content p c-heading f-500" href="' . esc_url(get_permalink()) . '">Przejdź' . '<svg class="result-mini-icon c-def" width="16" height="16" viewBox="0 0 16 16">
                <use xlink:href="#arrow-down-tiny"></use>
            </svg></a>';
            echo '</div>';
            echo '</div>';
        }
        echo '</div>';
        wp_reset_postdata();
    } else {
        echo '<p class="no-results">Nie znaleziono zabiegu.</p>';
    }

    wp_die();
}

请问我哪里出错了?或者有没有更好的方法在WordPress中合并并查询多个WP_Query对象的搜索结果?


错误分析

你的代码核心问题是创建完带post__in参数的$combined_results后,又重新赋值了一个空的WP_Query对象,直接覆盖了之前的查询结果,导致后续无法获取任何内容:

// 这里已经创建了正确的查询对象
$combined_results = new WP_Query(array(
    'post__in' => $combined_posts,
));

// 这行代码是无结果的根本原因,清空了之前的查询
$combined_results = new WP_Query();

另外还有两个潜在问题需要处理:

  • 合并ID数组时可能出现重复值,需要去重避免重复渲染结果
  • 如果合并后的数组为空,post__in会返回所有已发布文章,不符合搜索预期,需要提前判断

修复后的代码

function data_fetch() {
    check_ajax_referer('data_fetch_nonce', 'security');

    $keyword = isset($_POST['keyword']) ? sanitize_text_field($_POST['keyword']) : ''; 

    $page_query = new WP_Query(array(
        'fields' => 'ids',
        'posts_per_page' => -1,
        's' => $keyword,
        'post_type' => 'page',
        'post_status' => 'publish',
        'tax_query' => array(
            array(
                'taxonomy' => 'page_category',
                'field' => 'slug',
                'terms' => 'zabiegi',
            ),
        ),
    ));
    
    $custom_post_type_query = new WP_Query(array(
        'fields' => 'ids',
        'posts_per_page' => -1,
        's' => $keyword,
        'post_type' => 'uslugi',
        'post_status' => 'publish',
    ));
    
    // 合并数组并去重,重置索引避免WP_Query处理异常
    $combined_posts = array_unique(array_merge($page_query->posts, $custom_post_type_query->posts));
    $combined_posts = array_values($combined_posts);

    // 空数组直接返回无结果提示
    if (empty($combined_posts)) {
        echo '<p class="no-results">Nie znaleziono zabiegu.</p>';
        wp_die();
    }

    // 创建最终查询,指定文章类型并保留原数组顺序
    $combined_results = new WP_Query(array(
        'post__in' => $combined_posts,
        'post_type' => array('page', 'uslugi'),
        'post_status' => 'publish',
        'posts_per_page' => -1,
        'orderby' => 'post__in', // 按照合并数组的顺序返回结果
    ));

    if ($combined_results->have_posts()) {
        echo '<div class="search-results">';
        while ($combined_results->have_posts()) {
            $combined_results->the_post();
            echo '<div class="search-result-item">';
            echo '<div class="search-result-wrapper d-flex">';
            echo '<div class="result-content">';
            echo '<p class="result-title"><a class="p c-heading" href="' . esc_url(get_permalink()) . '">' . get_the_title() . '</a></p>';
            echo '</div>';
            echo '</div>';
            echo '<div class="result-action">';
            echo '<a class="result-content p c-heading f-500" href="' . esc_url(get_permalink()) . '">Przejdź<svg class="result-mini-icon c-def" width="16" height="16" viewBox="0 0 16 16"><use xlink:href="#arrow-down-tiny"></use></svg></a>';
            echo '</div>';
            echo '</div>';
        }
        echo '</div>';
        wp_reset_postdata();
    } else {
        echo '<p class="no-results">Nie znaleziono zabiegu.</p>';
    }

    wp_die();
}

更优的实现方案

其实不需要多次创建WP_Query,可以直接用一个WP_Query同时查询多种文章类型,并通过tax_query的关系参数实现复杂筛选,性能更优:

function data_fetch() {
    check_ajax_referer('data_fetch_nonce', 'security');

    $keyword = isset($_POST['keyword']) ? sanitize_text_field($_POST['keyword']) : ''; 

    $args = array(
        'posts_per_page' => -1,
        's' => $keyword,
        'post_type' => array('page', 'uslugi'), // 同时查询两种文章类型
        'post_status' => 'publish',
        'tax_query' => array(
            'relation' => 'OR', // 满足任意一个条件即可
            // 仅对page类型应用分类筛选
            array(
                'taxonomy' => 'page_category',
                'field' => 'slug',
                'terms' => 'zabiegi',
                'post_type' => 'page' // 指定该条件仅作用于page类型
            ),
            // 对uslugi类型设置一个始终为真的条件(无分类筛选要求)
            array(
                'taxonomy' => 'uslugi', // 替换为uslugi对应的分类法,若无则可换成其他逻辑
                'field' => 'id',
                'terms' => array(0),
                'operator' => 'NOT IN'
            )
        )
    );

    $combined_results = new WP_Query($args);

    if ($combined_results->have_posts()) {
        echo '<div class="search-results">';
        while ($combined_results->have_posts()) {
            $combined_results->the_post();
            echo '<div class="search-result-item">';
            echo '<div class="search-result-wrapper d-flex">';
            echo '<div class="result-content">';
            echo '<p class="result-title"><a class="p c-heading" href="' . esc_url(get_permalink()) . '">' . get_the_title() . '</a></p>';
            echo '</div>';
            echo '</div>';
            echo '<div class="result-action">';
            echo '<a class="result-content p c-heading f-500" href="' . esc_url(get_permalink()) . '">Przejdź<svg class="result-mini-icon c-def" width="16" height="16" viewBox="0 0 16 16"><use xlink:href="#arrow-down-tiny"></use></svg></a>';
            echo '</div>';
            echo '</div>';
        }
        echo '</div>';
        wp_reset_postdata();
    } else {
        echo '<p class="no-results">Nie znaleziono zabiegu.</p>';
    }

    wp_die();
}

这个方案的优势:

  • 仅执行一次数据库查询,性能更高效
  • 逻辑更简洁,避免数组合并和重复查询的问题
  • 通过tax_query的relation和post_type参数,精准控制不同文章类型的筛选规则

内容的提问来源于stack exchange,提问作者Pointless

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.26 09:44:52